标签:
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个人,分别编号0->N-1,已知有M个组,每组里面有若干人,一个人可分在多组中,0号是SARS感染者,如果某个人跟0号在一组,那么他有感染的嫌疑,还有如果某个人跟某个有感染嫌疑的人在一组,那么他也有感染嫌疑,问共有多少人有感染嫌疑。
包括0自己。
解析:并查集,对每一组,每个人都与第一个人并一次,最后查询有多少个人的根与0的根相同。
代码如下:
#include<cstdio>
#include<cstring>
#include<string>
#include<algorithm>
#include<set>
#include<map>
#include<queue>
#include<vector>
#include<iterator>
#include<utility>
#include<sstream>
#include<iostream>
#include<cmath>
#include<stack>
using namespace std;
const int INF=1000000007;
const double eps=0.00000001;
int d[100005];
int root(int a)
{
while(d[a]!=a) a=d[a];
return a;
}
void merg(int a,int b)
{
int ra=root(a);
int rb=root(b);
if(ra!=rb) d[ra]=rb;
}
int main()
{
int N,M;
while(cin>>N>>M)
{
if(!N&&!M) break;
for(int i=0;i<N;i++) d[i]=i;
for(int i=1;i<=M;i++)
{
int group;
scanf("%d",&group);
int id,pre;
for(int j=1;j<=group;j++)
{
scanf("%d",&id);
if(j==1) pre=id; //与第1个人合并
else merg(pre,id);
}
}
int ans=0;
int t=root(0);
for(int i=0;i<N;i++) if(root(i)==t) ans++; //根要相等
cout<<ans<<endl;
}
return 0;
}
标签:
原文地址:http://www.cnblogs.com/wust-ouyangli/p/4766455.html