并查集 题1

来源:互联网 发布:wiki.apache.org 编辑:程序博客网 时间:2024/05/22 10:59

问题描述
今天是Ignatius的生日。他邀请很多朋友。现在是晚餐时间。Ignatius想知道他至少需要多少张桌子。你必须注意到,并不是所有的朋友都认识对方,所有的朋友都不想留在陌生人身上。

这个问题的一个重要规则是,如果我告诉你A知道B,B知道C,这意味着A,B,C彼此认识,所以他们可以留在一个表中。

例如:如果我告诉你A知道B,B知道C,D知道E,所以A,B,C可以留在一个表中,D,E必须留在另一个表中。所以Ignatius至少需要2张桌子。
输入
输入开始于表示测试用例数的整数T(1 <= T <= 25)。然后T测试用例如下。每个测试用例从两个整数N和M开始(1 <= N,M <= 1000)。N表示朋友的数量,朋友的标记从1到N.然后M行跟随。每行由两个整数A和B(A!= B)组成,这意味着朋友A和朋友B彼此认识。两种情况之间会有一条空白线。
产量
样品输入
2
5 3
1 2
2 3
4 5

5 1
2 5
样品输出
2
4

并查集解析:http://blog.csdn.net/dellaserss/article/details/7724401/
写的非常好!!
转;

代码:

#include<stdio.h>#include<string.h>int pre[1005];int t[1005];int find(int x){    int r=x;    while(r!=pre[r])        r=pre[r];    int i=x,j;    while(pre[i]!=r)    {        j=pre[i];        pre[i]=r;        i=j;    }    return r;}void mix(int x,int y){    pre[x]=y;}int main(){    int n;    scanf("%d",&n);    while(n--)    {        int x,y;        scanf("%d%d",&x,&y);        for(int i=1;i<=x;i++)            pre[i]=i;        while(y--)        {            int z,b;            scanf("%d%d",&z,&b);            int q,p;            q=find(z);            p=find(b);            if(q!=p)                mix(q,p);                   }        memset(t,0,sizeof(t));        for(int i=1;i<=x;i++)            t[find(i)]=1;        int ans=0;         for(int i=1;i<=x;i++)            if(t[i]==1)                ans++;        getchar();        printf("%d\n",ans);    }       return 0; } 
原创粉丝点击