poj 1611 The Suspects(并查集)

103 阅读1分钟

题意:

0号为默认嫌疑人,所有跟0号曾经在同一个分组的也会被视为嫌疑人,只要是跟嫌疑人在一组过的都视为嫌疑人。

思路:

将每一组并入同一个集合,然后找到所有跟0相同根节点的人就可以了。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
using namespace std;
int fa[31000],te[31000];
int find(int h)  
{  
    if (h!= fa[h])  
    {  
        fa[h] = find(fa[h]); //这个回溯时的压缩路径是精华  
    }  
    return fa[h];  
} 
void uni(int c1,int c2)
{
         c1=find(c1) ;
        c2=find(c2) ;
        if(c1!=c2)
        {
                 fa[c1]=c2 ;
        }
}


int main(){
	int n,m,k;
	for(int i=1;i<1100;i++)
		fa[i]=i;
	while(scanf("%d%d",&n,&m),n||m){
		for(int i=0;i<n;i++)
			fa[i]=i;
		for(int t=0;t<m;t++){
			scanf("%d",&k);
			for(int h=0;h<k;h++){
				scanf("%d",&te[h]);
			}
			for(int i=0;i<k-1;i++)
				uni(te[i],te[i+1]);
		}
		int co=0,de;
		de=find(0);
		for(int i=0;i<n;i++)
			if(find(i)==de) co++;
		printf("%d\n",co);
	//	for(int i=0;i<n;i++)
		//	printf("%d ",find(i)); 
	
	} 
	
	return 0;
}


\