1. 程式人生 > >暢通工程(並查集基本應用)

暢通工程(並查集基本應用)

con () 之間 clas count eof out 統計 %d

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 解題思路:並查集的基本應用,將各個城鎮分成n個集合,要使全部的城鎮都有連接,那麽還需要n-1條通路。
 1
#include<stdio.h> 2 int pre[1010]; 3 int findx(int x)///查找根節點 4 { 5 int a; 6 a=x; 7 while(pre[a]!=a) 8 { 9 a=pre[a]; 10 } 11 return a; 12 } 13 void combine(int root1,int root2)///合並路線 14 { 15 int x,y; 16 x=findx(root1); 17 y=findx(root2);
18 if(x!=y) 19 { 20 pre[x]=y; 21 } 22 } 23 int main() 24 { 25 int n,m,i,x,y,count; 26 while(scanf("%d%d",&n,&m)!=EOF) 27 { 28 if(n==0) 29 { 30 break; 31 } 32 count=0; 33 for(i=1; i<=n; i++) 34 { 35 pre[i]=i;///初始化 36 } 37 while(m--) 38 { 39 scanf("%d%d",&x,&y); 40 combine(x,y); 41 } 42 for(i=1;i<=n;i++) 43 { 44 if(pre[i]==i)///統計利用並查集將各個城鎮分成的集合的個數 45 { 46 count++; 47 } 48 } 49 printf("%d\n",count-1);///若有n個集合那麽便要新建n-1條通路 50 } 51 return 0; 52 }

暢通工程(並查集基本應用)