ACM_“打老虎”的背后(简单并查集)

“打老虎”的背后

Time Limit: 2000/1000ms (Java/Others)

Problem Description:

“习大大”自担任国家主席以来大力反腐倡廉,各地打击贪腐力度也逐步加强。中国的这种令外国人不解的“风情”到底是何缘由呢?其实中国人都知道,所有的腐败问题基本上都源自官场上的“潜规则”,那“潜规则”又是源自什么呢?在中国盛行一句古语,“无关系不成方圆”,说的是中国是一个人情社会,纽带关系很强。一个人跟另一个人可能存在沾亲带故的某种“关系”,而所有通过这种“关系”的传递关系之后就产生了一个个的“关系网”。
假设现在存在n个人编号:1,2,3,...,n.当中存在k个一对一“关系”:(a,b),你能帮忙求出n个人当中存在几个“关系网”吗?
例如:当n=4,k=3(1--2 2--4 4--2)时,存在2个关系网:(1,2,4)和(3)。

Input:

输入包含多组测试数据。每一组测试第一行输入两个正整数n,m(n,m<=10000),表示n个人之中存在m个的“关系”;
下面m行每一行输入a,b(1 <= a,b <= n且a!=b)表示a和b之间存在关系,其中(a,b)可能重复出现。

Output:

对于每一组测试,输出n个人形成的“关系网”的个数,占一行。

Sample Input:

4 3
1 2
2 4
4 2
6 3
1 2
3 4
5 6

Sample Output:

2
3
解题思路:简单并查集,找出连通分量的个数即可,水过!
AC代码:
 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 const int maxn=10005;
 4 int n,m,a,b,num,fa[maxn];
 5 void init(){
 6     for(int i=1;i<=n;++i)fa[i]=i;
 7 }
 8 int findt(int x){
 9     int tmp,pir=x;
10     while(fa[pir]!=pir)pir=fa[pir];
11     while(x!=pir){tmp=fa[x];fa[x]=pir;x=tmp;}//路径压缩
12     return x;
13 }
14 void unite(int x,int y){
15     x=findt(x),y=findt(y);
16     if(x!=y)fa[x]=y;
17 }
18 int main(){
19     while(~scanf("%d%d",&n,&m)){
20         init();num=0;
21         while(m--){scanf("%d%d",&a,&b);unite(a,b);}
22         for(int i=1;i<=n;++i)
23             if(fa[i]==i)num++;
24         printf("%d\n",num);
25     }
26     return 0;
27 }

猜你喜欢

转载自www.cnblogs.com/acgoto/p/9222002.html