POJ 1611 The Suspects 并查集

来源:互联网 发布:emlog5.3.1源码下载 编辑:程序博客网 时间:2024/05/21 07:12

大学里总共有n个学生,m个社团。学生的编号从0到(n-1)。每个学生可以参加多个社团。现在0号学生疑似感染了SARS。与疑似感染者同一个社团的人都是疑似感染者。求疑似感染者总数。


这是一个简单的并查集题目。初始时,每个学生都各是一个集合。然后把同一社团的学生都合并到同一集合去。完成合并后,0号学生所在的集合的元素个数即是疑似感染者总数。


#include <stdio.h>#define MAX 30005//并查集//还有一种设置并查集的办法:将father[]都初始化为-1,然后利用祖宗的father[]记录负的集合元素数。int father[MAX];int findset(int x){    int fx = x,tmp;    while(fx != father[fx])//找到x的最老的祖宗        fx = father[fx];    while(x != father[x])//路径压缩:把x的各级father都置为最老的祖宗    {        tmp = father[x];        father[x] = fx;        x = tmp;    }    return fx;}void unionset(int x,int y){    x = findset(x);    y = findset(y);    if(x < y)//让编号最小的成为最老的祖宗,这是为了让0号学生成为代表元素        father[y] = x;    else        father[x] = y;    return;}int main(){    int m,n,k,i,j,suspects,tmp1,tmp2;    //FILE *fp = NULL;//    if(NULL == (fp = fopen("t.txt","r")) )//        printf("cannot open file.\n");    while(1)    {        suspects = 0;        //fscanf(fp,"%d %d",&n,&m);        scanf("%d %d",&n,&m);        if(0 == m && 0 == n)            break;        if(0 == m)        {            suspects = 1;            printf("%d\n",suspects);            continue;        }        for(i=0;i<n;i++)//make set            father[i] = i;        for(i=0;i<m;i++)        {            //fscanf(fp,"%d",&k);            scanf("%d",&k);            //fscanf(fp,"%d",&tmp1);            scanf("%d",&tmp1);            for(j=1;j<k;j++)            {                //fscanf(fp,"%d",&group[j]);                scanf("%d",&tmp2);                unionset(tmp1,tmp2);            }        }        for(i=0;i<n;i++)            //if(0 == father[i])            if(0 == findset(i))                suspects++;        printf("%d\n",suspects);    }    return 0;}


原创粉丝点击