标签:poj
| Time Limit: 1000MS | Memory Limit: 20000K | |
| Total Submissions: 21427 | Accepted: 10375 |
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
题意:n,表示学生数目, m,表示社团数目, 每个学生有一个编号, 0到N-1, 编号为0的学生是所有学生中最初的唯一感染者, 接下来由m个社团, 在每行输入一个k
,k表示社团的总人数, 接着是社团中k个成员的编号。。 当输入n=0且m=0时,输入结束。。输出被感染的总人数。。
解题思路:
本题编号为0的人已经被感染了,所以被感染的人数至少为1
运用并查集划分集合的同时记录每一个集合 的元素个数。。
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<vector>
#include<queue>
#include<sstream>
#include<cmath>
using namespace std;
#define f1(i, n) for(int i=0; i<n; i++)
#define f2(i, n) for(int i=1; i<=n; i++)
#define f3(i, n) for(int i=n; i>=1; i--)
#define f4(i, n) for(int i=2; i<=n; i++)
#define M 30050
int n;
int p[M];
int r[M];
int a[M];
void start()
{
for(int i=0; i<=n-1; i++)
{
p[i]=i; //初始化并查集
r[i]=1; //初始化时,每个元素作为一个集合,其元素为1
}
}
int find(int x) //并查集的find
{
return p[x] == x ? x : p[x] = find ( p[x] );
}
void Kruskal(int x, int y)
{
int xx = find(x);
int yy = find(y); //找出当前两个端点所在集合的编号
//如果在不同集合就合并
if(xx!=yy)
{
r[xx] += r[yy]; //合并时更改集合元素的总数
p[yy] = xx;
}
}
int main()
{
int m;
while(scanf("%d%d",&n,&m)!=EOF)
{
if(n==0 && m==0)
break;
start();
while( m-- )
{
int t;
scanf("%d", &t);
f1(i, t)
{
scanf("%d", &a[i]);
if(i!=0)
Kruskal(a[i-1], a[i]);
}
}
printf("%d\n", r[find(0)]);//找到包含0元素的集合的节点,并输出其记录的节点数目
}
return 0;
}
POJ 1611 :The Suspects(并查集),布布扣,bubuko.com
标签:poj
原文地址:http://blog.csdn.net/u013487051/article/details/37764759