HDU - 1232 暢通工程(並查集)
阿新 • • 發佈:2018-11-29
某省調查城鎮交通狀況,得到現有城鎮道路統計表,表中列出了每條道路直接連通的城鎮。省政府“暢通工程”的目標是使全省任何兩個城鎮間都可以實現交通(但不一定有直接的道路相連,只要互相間接通過道路可達即可)。問最少還需要建設多少條道路?
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.
Hint
Hint
題意:給出城市的數量,和已經修好的道路數目,然後給出已經修好的道路所連線的兩個城市,問還需要修多少道路,所有的城市可以連通。
注意:(但不一定有直接的道路相連,只要互相間接通過道路可達即可)
題解:先表示一下所有城市連通所需要的全部道路,很顯然是n-1條,然後兩個城市是連通的減一條,剩下的就是需要修的道路數目。詳細看程式碼:
import java.util.*; public class Main{ static Scanner cin = new Scanner(System.in); static int [] f; static int find(int x) {//判斷兩個城市是否連起來了 //return x==f[x]? x:f[x]=find(f[x]);//這樣寫編譯不通過,我很迷,不過,C++可以 return x!=f[x]? f[x]=find(f[x]):x;//這樣寫可以 // if(f[x]!=x) f[x]=find(f[x]);//這樣寫可以 // return f[x]; } static void lianjie(int u,int v) {//如果兩個城市有道路連線起來 int root1=find(u); int root2=find(v); if(root1!=root2) { f[root1]=root2; } } public static void main(String[] args) { int n,m; int ans; while(cin.hasNext()) { n=cin.nextInt(); if(n==0) break; m=cin.nextInt(); f=new int[n+10]; ans=n-1;//需要道路總數 for (int i = 1; i <= n;i++) { f[i]=i;//初始化為自己和自己連著 } while(m-->0) { int u,v; u=cin.nextInt();v=cin.nextInt(); if(find(u)!=find(v)) { lianjie(u,v); ans--;//如果兩個城市有道路連線 總數減一 } } System.out.println(ans); } } }