1. 程式人生 > >HDU-1232-通暢工程(並查集)

HDU-1232-通暢工程(並查集)

合並 目標 說明 道路 調查 兩個 sample 枚舉集合 連通

Problem Description 某省調查城鎮交通狀況,得到現有城鎮道路統計表,表中列出了每條道路直接連通的城鎮。省政府“暢通工程”的目標是使全省任何兩個城鎮間都可以實現交通(但不一定有直接的道路相連,只要互相間接通過道路可達即可)。問最少還需要建設多少條道路?

Input

測試輸入包含若幹測試用例。每個測試用例的第1行給出兩個正整數,分別是城鎮數目N ( < 1000 )和道路數目M;隨後的M行對應M條道路,每行給出一對正整數,分別是該條道路直接連通的兩個城鎮的編號。為簡單起見,城鎮從1到N編號。
註意:兩個城市之間可以有多條道路相通,也就是說
3 3
1 2
1 2
2 1
這種輸入也是合法的
當N為0時,輸入結束,該用例不被處理。


Output

對每個測試用例,在1行裏輸出最少還需要建設的道路數目。


Sample Input

4 2
1 3
4 3
3 3
1 2
1 3
2 3
5 2
1 2
3 5
999 0
0

Sample Output

1
0
2
998


        
 
Huge input, scanf is recommended.

思路:並查集模板題。合並有路的兩個城市為一個集合。最後枚舉集合個數再減1就是聯通所需的最少路數。


#include<cstdio>
int bin[1002];
 
int findx(int x)//找到x所在的集合編號 
{
    
    while
(bin[x]!=x)//這裏註意一下!是循環好多次啊,找最終一個bin[x]==x的x值! 就是編號 x=bin[x]; return x; } void merge(int x,int y)//合並函數 { int fx,fy; fx = findx(x); fy = findx(y); if(fx != fy)//如果他倆編號不一樣就讓 bin[fx]=fy;//就讓x的編號節點指向y的編號節點 ,從而形成一個集合 } int main() { int n,m,i,x,y,cnt; while(scanf("
%d",&n)&&n) { for(i=1;i<=n;i++) bin[i] = i; //現在有n個集合 for(scanf("%d",&m);m>0;m--) {//將兩個集合合並 scanf("%d %d",&x,&y); merge(x,y); } cnt=0; for(i=1;i<=n;i++)//n給節點遍歷一遍 if(bin[i]==i)//如果是編號節點就說明有一個集合 cnt++; printf("%d\n",cnt-1); } }

HDU-1232-通暢工程(並查集)