题目大意:n(30,000)个学生假如m(500)组,一个人可以加入多组,这堆学生被编号(0—n-1),编号为0的学生有病,一个组的人可以相互接触,问有多少人可以和0号学生接触(包括0号学生他自己)
#include<iostream>
#include<string.h>
#define N 30000+500
#define M 500+50
using namespace std;
int boss[N]={0};
int n;
int m;
void init()
{
for(int i=0;i<n;i++)
{
boss[i]=i;
}
}
void connect(int x,int y)
{
if(x==0&&boss[y]==y)
{
boss[y]=0;
return;
}
if(y==0&&boss[x]==x)
{
boss[x]=0;
return;
}
if(boss[x]==x&&boss[y]==y)
{
boss[x]=y;
return;
}
boss[x]=boss[boss[x]];
boss[y]=boss[boss[y]];
connect(boss[x],boss[y]);
}
void ceshi1()
{
for(int i=0;i<n;i++)
{
cout<<i<<":"<<boss[i]<<" ";
}
}
int find()
{
int s=0;
for(int i=0;i<n;i++)
{
int x=i;
while(1)
{
if(boss[x]==0)
{
//cout<<x;
s++;break;
}
/*cout<<i<<" "<<boss[i]<<" ";
ceshi1();cout<<endl<<endl;*/
if(boss[x]==x)
{
break;
}
x=boss[x];
}
}
return s;
}
int main()
{
while(cin>>n>>m)
{
if(m==0&&n==0)break;
init();
for(int i=0;i<m;i++)//输入m行数据
{
int l;
cin>>l;
l--;
int x;
cin>>x;
while(l--)
{
int t;
scanf("%d",&t);
connect(x,t);
}
}
//ceshi1();
cout<<find()<<endl;
}
}
并查集,大概就是这样吧,然后注意别出现环,再写快一点。