| Time Limit: 1000MS | Memory Limit: 20000K | |
| Total Submissions: 21586 | Accepted: 10456 |
Description
Input
Output
Sample Input
100 4 2 1 2 5 10 13 11 12 14 2 0 1 2 99 2 200 2 1 5 5 1 2 3 4 5 1 0 0 0
Sample Output
4 1 1
Source

题意直接从YM那里复制过来的。http://www.cnblogs.com/yym2013/p/3845448.html
parent[i] 表示 i号节点的根节点是谁,sum[i] 表示以i号节点为根节点的总节点个数,那么sum[0]即为所求。
在合并的时候需要稍微处理一下,如果find(x) fin(y)有一个为0时,始终把0作为根节点,也就是说,第0个节点始终在自己的集合中。 这样最后直接输出sum[0]就可以了。
代码:
#include <iostream>
using namespace std;
const int maxn=30010;
int parent[maxn];
int sum[maxn];
int st[maxn];
void init(int n)
{
for(int i=0;i<n;i++)
{
parent[i]=i;
sum[i]=1;
}
}
int find(int x)
{
return parent[x]==x?x:find(parent[x]);
}
void unite(int x,int y)
{
int t1=find(x);
int t2=find(y);
if(t1==t2)
return ;
if(t1==0)//始终连接到根为0的节点上
{
parent[t2]=t1;
sum[t1]+=sum[t2];
}
else if(t2==0)
{
parent[t1]=t2;
sum[t2]+=sum[t1];
}
else //如果二者的根不为0 ,那就随便了。
{
parent[t1]=t2;
sum[t2]+=sum[t1];
}
}
int main()
{
int n,m;
while(cin>>n>>m&&(n||m))
{
init(n);
int k;//每组多少个数
while(m--)
{
cin>>k;
cin>>st[0];//就算0个团体0个人,也要输入第一个人,汗
k--;
for(int i=1;i<=k;i++)
{
cin>>st[i];
unite(st[i],st[i-1]);
}
}
cout<<sum[0]<<endl;
}
return 0;
}
[ACM] POJ 1611 The Suspects (并查集,输出第i个人所在集合的总人数),布布扣,bubuko.com
[ACM] POJ 1611 The Suspects (并查集,输出第i个人所在集合的总人数)
原文:http://blog.csdn.net/sr_19930829/article/details/37900239