题目链接: http://vjudge.net/problem/viewProblem.action?id=10536
题目意思:给你 n 个人 m 个小组 , 给m行 每行描述属于这个组的人的编号。每个人的编号从 0 到 N-1 ; 0这个学生是被感染的,跟他同个组织的人都被感染,而且只要某个组里有一个人感染则其他人也感染。让你判断有多少人感染。
分析: 并查集的应用,判断连通性。
#include<stdio.h>
#include<cmath>
#include<iostream>
#include<algorithm>
#include<string.h>
#include<queue>
using namespace std;
#define MAX 30005
int father[MAX];
int find(int x) //朴素的查找方法
{
while(father[x] != x)
{
x = father[x];
}
return x;
}
void Merge(int a, int b)
{
int aa = find(a);
int bb = find(b);
if(aa == bb) return ;
else father[aa] = bb;
}
int a[MAX];
int main()
{
int i,j,k,n,m;
while(scanf("%d%d",&n,&m) != EOF )
{
if(n==0&& m==0 ) break;
for(i=0;i<n;i++)
father[i] = i;
int ans = 0;
while(m--)
{
scanf("%d%d",&k,&a[0]);
for(i=1;i<k;i++)
{
scanf("%d",&a[i]);
Merge(a[0],a[i]);
}
}
int root = find(0); //一开始这里写成if (fine(0) == find (i))
for(i=0;i<n;i++) // 一直TLE,主要是因为前面的find没有用到路径压缩所以超时。
{
if(root == find(i))
ans++;
}
printf("%d\n", ans);
}
return 0;
}
int find (int x ) //路径压缩 节省很多时间
{
if(x != father[x])
return find(father[x]);
return x ;
}