1079 : [啊哈算法]擒贼先擒王(并查集)
Description
警察想查清楚有几个犯罪团伙,搜集到了一些线索:
现在有10个强盗;
1号强盗与2号强盗是同伙;
3号强盗与4号强盗是同伙;
5号强盗与2号强盗是同伙;
4号强盗与6号强盗是同伙;
2号强盗与6号强盗是同伙;
8号强盗与7号强盗是同伙;
9号强盗与7号强盗是同伙;
1号强盗与6号强盗是同伙;
2号强盗与4号强盗是同伙;
强盗同伙的同伙也是同伙,请问一共有多少个独立的犯罪团伙?
Input
第一行n,m,分别表示强盗人数,和线索条数,接下来m行有两个数a,b,表示a和b是同伙。
Output
输出一个整数,表示犯罪团伙的数量
Sample Input
10 9 1 2 3 4 5 2 4 6 2 6 8 7 9 7 1 6 2 4
Sample Output
3
1 #include<iostream> 2 using namespace std; 3 int n,m,f[103],sum; 4 int getf(int x){//递归找到x的最终头领 5 if(f[x]==x)//如果x的头领是自己,就返回 6 return x; 7 else{ 8 f[x]=getf(f[x]);//递归 这里有一个优化 9 //如果不优化,可以这么写 getf(f[x]); 10 //优化后速度快些 11 return f[x]; 12 } 13 } 14 void merge(int x,int y){//合并两个集合 15 int t1,t2; 16 t1=getf(x); 17 t2=getf(y); 18 if(t1!=t2){ 19 f[t2]=t1;//偏左原则 20 } 21 } 22 int main(){ 23 cin>>n>>m; 24 int a,b; 25 for(int i=1;i<=n;i++) 26 f[i]=i; 27 for(int i=1;i<=m;i++){ 28 cin>>a>>b; 29 merge(a,b); 30 } 31 for(int i=1;i<=n;i++){ 32 if(f[i]==i)//如果自己的头领是自己,那么就代表一个集合 33 sum++; 34 } 35 cout<<sum; 36 return 0; 37 }