这个问题有两个解法,其实是我在面试百度的三面题目
当时用的是并查集的思想。但是没有用并查集做,而是直接合并了。所以导致算法时间复杂度上升,如果三面跪了应该就是跪在这题上面了。
另外一个方法是把他看做求最大联通子图的问题,用遍历的方法就可以解决。
以下列出并查集的算法。
import java.io.BufferedInputStream;
import java.util.HashSet;
import java.util.Scanner;
public class Main {
static int n;
static int m;
static HashSet<Integer> set;
public static void main(String[] args) {
Scanner s = new Scanner(new BufferedInputStream(System.in));
while(s.hasNextInt()){
n = s.nextInt();
if(n==0)
break;
m = s.nextInt();
int father[] = new int[n];
for(int i=0; i<n; i++)
father[i] = i;
for(int i=0; i<m; i++){
int x = findF(father,s.nextInt()-1);
int y = findF(father,s.nextInt()-1);
if(x != y)
father[y] = father[x]; //合并两个集合
}
int count=0;
for(int i=0;i<father.length;i++){
if(father[i]==i){
count++;
}
}
System.out.println(count-1);
}
}
private static int findF(int []father,int a) {
int b=a;
while(father[a] != a)
a = father[a];
father[b]=a;
return father[a];
}
}