标签:
链接:http://poj.org/problem?id=1611
| Time Limit: 1000MS | Memory Limit: 20000K | |
| Total Submissions: 27854 | Accepted: 13583 |
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
题意:有很多组学生,在同一个组的学生经常会接触,也会有新的同学的加入。但是SARS是很容易传染的,
只要在改组有一位同学感染SARS,那么该组的所有同学都被认为得了SARS。现在的任务是计算出有
多少位学生感染SARS了。假定编号为0的同学是得了SARS的
分析:用并差集。用nod[x].father记录其父节点,nod[x].number表示集合成员个数,nod[x].rank表示集合的层数。
<span style="font-size:18px;">#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
const int maxn=30030;
int n,m;
struct node{
int father;
int number;
int rank;
}nod[maxn];
void init()//初始化
{
for(int i=0;i<n+1;i++)
{
nod[i].father=i;
nod[i].number=1;
nod[i].rank=0;
}
}
int find(int x){ //路径压缩的父节点查找
int r=x,temp;
while(r != nod[r].father) r=nod[r].father;
while(r != x)
{
temp=nod[x].father;
nod[x].father=r;
x=temp;
}
return x;
}
void unite(int x,int y) //按高度合并
{
int fx=find(x);
int fy=find(y);
if(fx==fy) return;
if(nod[fx].rank>nod[fy].rank)
{
nod[fy].father=fx;
nod[fx].number +=nod[fy].number;
}
else
{
nod[fx].father=fy;
nod[fy].number +=nod[fx].number;
if(nod[fx].rank==nod[fy].rank)
nod[fy].rank++;
}
}
int main()
{
int t,a,b;
while(scanf("%d %d",&n,&m) &&(n||m))
{
init();
for(int i=0;i<m;i++)
{
scanf("%d",&t);
if(t>1)
{
--t;
scanf("%d",&a);
while(t--)
{
scanf("%d",&b);
unite(a,b);
a=b;
}
}
else scanf("%d",&a);//当t=1时记得要读入,刚开始我忘记读入了,EL了整个上午,,orz
}
int ans=find(0);
printf("%d\n",nod[ans].number);
}
return 0;
}
</span>版权声明:本文为博主原创文章,转载记得著名出处,谢谢!
标签:
原文地址:http://blog.csdn.net/hellohelloc/article/details/48088407