您的位置:首页 > 其它

POJ 1611 The Suspects

2016-08-08 10:16 183 查看




题目大意:有一个学校,有n个学生,编号为0-n-1,现在0号学生感染了非典,凡是和0在一个社团的人就会感染,并且这些人如果还参加了别的社团,他所在的社团照样全部感染,打印感染的人数。

解题思路:明显一道并查集的题,就是求与0有关系的那条线一共有多少个 在输入社团的时候 给出了那些人是一个社团 这里处理下 因为给出m个社团 以下m行都是社团信息 先是一个社团的总人数 因为是总人数不好合并的 所以我们开个数组来存储 输入到第二个开始我们就开始合并 让这个社团中的人通通指向第一个人 这样就可以完成他们的合并。

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <algorithm>
#include <map>
#include <cmath>
#include <queue>
#include <string>
#include <vector>

using namespace std;

#define FOR(i,m)  for(int i=0;i<m;i++)
#define sc(x) scanf("%d",&x)
#define lcr(a,b) memset(a,b,sizeof(a));
#define pr(x) printf("%d\n",x)

const int maxn=3e4+5;
int n,m,num;
int p[maxn],k[maxn],a[maxn];
void init()
{
for(int i=0;i<n;i++)
{
p[i]=i;
k[i]=1;//来记录人数
}
}
int Find(int x)//查找函数
{
if(x!=p[x])
{
p[x]=Find(p[x]);
}
return p[x];
}
void Unionset(int x,int y)
{
int xx=Find(x);
int yy=Find(y);
if(xx!=yy)
{
p[yy]=xx;//合并
k[xx]+=k[yy];//当前社团的总人数
}
}
int main()
{
while(~scanf("%d %d",&n,&m))
{
if(n==0&&m==0)
break;
init();//初始化函数
while(m--)
{
sc(num);
FOR(i,num)
{
scanf("%d",&a[i]);
if(i>=1)
{
Unionset(a[i-1],a[i]);//合并函数
}
}
}
pr(k[Find(0)]);//0的最高级对应的人数
}
return 0;
}


END!!!!!!!!!!!!!!!!!!
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: