Input
測試輸入包含若干測試用例。每個測試用例的第1行給出兩個正整數,分別是城鎮數目N ( < 1000 )和道路數目M;隨后的M行對應M條道路,每行給出一對正整數,分別是該條道路直接連通的兩個城鎮的編號。為簡單起見,城鎮從1到N編號。?
注意:兩個城市之間可以有多條道路相通,也就是說
3 3
1 2
1 2
2 1
這種輸入也是合法的
當N為0時,輸入結束,該用例不被處理。?
注意:兩個城市之間可以有多條道路相通,也就是說
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
這題是一個很經典的并查集題目了,也是最基礎的了,當做學習~
import java.util.Scanner;public class Main {public static int[] parent;public static boolean[] root;public static int find(int x){int top = x;
//找出頂層父節點while(parent[top] != top){top = parent[top];}//減少深度,路徑壓縮int c2 = x; int temp;while(c2!=top){temp = parent[c2];parent[c2] = top;c2 = temp;}return top;}public static void union(int x,int y){int fx = find(x);int fy = find(y);
//如果不是同一頂層父節點則隨機一個聯合if(fx != fy){parent[fy] = fx;}}public static void main( String[] args ) {Scanner sc = new Scanner(System.in);int n,m;while(sc.hasNext()){int answer=0;n = sc.nextInt();if(n==0) return ;m = sc.nextInt();parent = new int[n+1];root = new boolean[n+1];for(int i=1;i<=n;i++){parent[i] = i;}for(int i=0;i<m;i++){union( sc.nextInt(), sc.nextInt() );}for(int i=1;i<=n;i++){root[find( i )] = true;}for(int i=1;i<=n;i++){if(root[i]){answer++;}}System.out.println( answer-1 );}} }
?