(並查集) HDU 1232 暢通工程

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
 
Hint
Huge input, scanf is recommended. 
 
 
根據題意,這個題能夠用並查集,就是把已經聯通的路併到一個集合,而後統計有多少個集合,最後獲得的結果是集合的個數減去1。
C++代碼:
#include<iostream>
#include<cstdio>
using namespace std;
const int maxn = 1010;
int father[maxn];
//查找根。
int Find(int x){
    while(x != father[x]){
        father[x] = father[father[x]];  //路徑壓縮。
        x = father[x];
    }
    return x;
}
//合併操做
void Union(int a,int b){
    int ax = Find(a);
    int bx = Find(b);
    if(ax != bx){
        father[ax] = bx;
    }
}
int main(){
    int N,M;
    while(~scanf("%d",&N)){
        if(N == 0) break;
        cin>>M;
                //初始化。
        for(int i = 1; i <= N; i++){
            father[i] = i;
        }
        int a,b;
        for(int i = 1; i <= M; i++){
            cin>>a>>b;
            Union(a,b);
        }
        int res = 0;
        for(int i = 1; i <= N; i++){
            if(father[i] == i)
                res++;
        }
        cout<<res-1<<endl;
    }
    return 0;
}    
相關文章
相關標籤/搜索