并查集-按秩合并

来源:互联网 发布:淘宝名字大全2016款女 编辑:程序博客网 时间:2024/06/08 20:31

1239: 中山学院 ACM小组

Time Limit: 1 Sec  Memory Limit: 64 MB
Submit: 79  Solved: 21
[Submit][Status][Web Board]

Description

经过几年的发展,中山学院 ACM队伍越来越庞大,水平越来越高,影响力也越来越大。随着人员数量的壮大,为了营造一个良好的队内之间沟通讨论氛围,教练组决定让队员之间以小组的形式进行讨论。而教练组又希望所有认识的人都在同一组里面讨论,以提高大家的积极性。而这里的认识可以是直接认识或是间接认识(如果A和 B认识,B 和 C认识,这时A和C可以通过B从而使三个人成为同一个小组的成员。四个人以上的做类似的处理。),假如有一个人他谁都不认识,那么没办法了,他只能自己呆在角落发呆了。当然,他自己也算一个讨论组。同时每个队员都有一个唯一的编号,编号从0 到 n-1(n是队员总数)。现在队伍里面有n个人,跟m组关系,每组关系有两个数a,b,表示a跟b相互认识。那么现在问你,我们学校ACM队伍里面一共组成了多少个讨论组?并且对于每个队员,你是否知道他所属讨论组的人数有多少?

Input

对于每组输入,第一行为两个数n 和 m, (1 <=n <=100,1 <=m<=100),分别代表ACM队内的总人数n和m组关系。接下来的m行,每行有两个数 a 和b,a 和b 是队员的编号,表示 a 和 b认识(0 <= a,b<=n-1)。下面一行输入一个整数k,代表有k组询问,后面的k行每行输入一整数 x,表示此次询问编号为x 的队员所属小组的人数。 (n 和m同时为0时输入结束)

Output

第一行输出讨论小组的数目(格式为”X groups in Zsc_Acmer Camp”,其中X表示讨论小组数目)后面的k行,每一行输出对应询问的回答。

Sample Input

5 30 11 20 2501234

Sample Output

3 groups in Zsc_Acmer Camp33311
#include<iostream>#include<cstdio>#include<cstring>using namespace std;int d[500],s[500];int find(int x){    int k,j,r;    r=x;    while(r!=d[r])        r=d[r];    k=x;    while(k!=r)    {        j=d[k];        d[k]=r;        k=j;    }    return r;}void unio(int x,int y){    x=find(x);    y=find(y);    if(x==y)        return ;    if(s[x]>=s[y])    {        d[y]=x;        s[x]+=s[y];    }    else    {        d[x]=y;        s[y]+=s[x];    }}int main(){    int n,m,a,b,ki,tt;    while(~scanf("%d%d",&n,&m))    {        if(n==0&&m==0)            break;        for(int i=0;i<n;i++)        {            d[i]=i;            s[i]=1;        }        while(m--)        {            scanf("%d%d",&a,&b);            unio(a,b);        }        int cas=0;        for(int i=0;i<n;i++)        {            if(d[i]==i)                cas++;        }        printf("%d groups in Zsc_Acmer Camp\n",cas);        scanf("%d",&ki);        while(ki--)        {            scanf("%d",&tt);            int aa=find(tt);            printf("%d\n",s[aa]);        }    }    return 0;}

0 0
原创粉丝点击