解析:本题本质就是并查集的变形,我的想法是每一组输入时,把最小的数作为全组的父节点,然后用一个set记录下所有数据(剔除重复数),最后再for循环set中的数据,如果该数据的父节点是0,那么就是有被感染的嫌疑。
代码如下:
#include<iostream>
#include<vector>
#include<algorithm>
#include<set>
using namespace std;
int parent[30001];
int find(int* p,int r)
{
while(p[r]!=r)
r=p[r];
return r;
}
int main()
{
int n,m;
while(1)
{
cin>>n>>m;
if(n==0&&m==0)
break;
else if(m==0)
{
cout<<n<<endl;
}
else{
set<int> sum;
for(int i=0;i<n;i++)
{
parent[i]=i;
}
for(int i=0;i<m;i++){
int zu;
int x;
int y;
cin>>zu>>x;
sum.insert(x);
for(int j=1;j<zu;j++)
{
cin>>y;
sum.insert(y);
int a=find(parent,x);
int b=find(parent,y);
if(a>b)
{
parent[a]=b;
}
else if(a<b)
{
parent[b]=a;
}
x=y;
}
}
sum.insert(0);
int ans=0;
set<int>::iterator it;
for(it=sum.begin();it!=sum.end();it++)
{
if(find(parent,*it)==0)
ans++;
}
cout<<ans<<endl;
}
}
return 0;
}