CUIT-ACM 01-16 F

F - The Suspects POJ - 1611
题目大意:
有一部分人得SARS一部分人没得病,现在知道这些学生曾经组成过很多团体,一个学生可加入多个团体。现在得知SARS有极强的传染性Once a member in a group is a suspect, all members in the group are suspects. (一旦有一个人患病整个团体的每个人都有可能患病),现在对不同的学生进行编号,编号为0的为患SARS病的学生。(和0在一起的团体内的所有成员全部为疑似病患者)
INPUT
学生的最大编号max1 团体总数n(第一群人)
团体1的成员数k1 成员a1 成员b1……成员m1(一共k1个成员)
团体2的成员数k2 成员a2 成员b2……成员m2(一共k2个成员)
……
团体n的成员数kn 成员an 成员bn……成员mn(一共kn个成员)
学生的最大编号max2 团体总数n'(第二群人)
团体1的成员数k1 成员a1 成员b1……成员m1(一共k1个成员)
团体2的成员数k2 成员a2 成员b2……成员m2(一共k2个成员)
……
团体n的成员数kn' 成员an' 成员bn'……成员mn'(一共kn'个成员)
……
……
OUTPUT
第一群人疑似患病人数
第二群人疑似患病人数
……
思路:
并查集知识
将每个的所有人全部连接在一起,将能连接在一起的成员(元素)标记为n(n为连接中所有元素中最小的那个元素)
查找所有元素中被标记为0的人数(即和0相连通的元素的个数)
代码:
https://vjudge.net/solution/7923560/gVoVX6l7kT3dhgYMpxB6

#include
using namespace std;
int pre[31000];
int i,j,m,n,k,a,a0,cnt;
int Find(int x)
{
    if(pre[x] == x) return x;
    else return Find(pre[x]);
}

void Union(int x,int y)
{
    int X = Find(x);
    int Y = Find(y);
    if(X > Y) pre[X] = Y;
    else pre[Y] = X;
}

void ini()
{
    for(int i=0; i

并查集知识:
模版:

#include
#define maxn 1010
using namespace std;

int pre[maxn];

int Find(int x)
{
    if(pre[x] == x) return x;
    else return Find(pre[x]);//找到x的根
}

void Union(int x,int y)
{
    int X = Find(x);
    int Y = Find(y);
    if(X != Y) pre[Y] = X;//两个数p、q如果被标记的数等于自己本身,则将其中一个数的标记改变(即表示这2个数相连)(不相连的数字序号就是自己本身)
}

void ini()
{
    for(int i=1; i<=10; i++)
    {
        pre[i] = i;//将所有数标记为1~n(使得最开始每个元素都是有独立(不同)的标记的)
    }
}
int main()
{
    int q,p;
    ini();
    while(~scanf("%d%d",&q,&p))//输入2个数p、q
    {
        if(q == 0 && p == 0)//p、q同时为0则结束程序
            break;
        if(Find(q) == Find(p))//q和p的根相同(p、q已经相连)
        {
            printf("YES\n");
        }
        else
        {
            printf("NO\n");
            Union(q,p);//连接q和p
            if(Find(q) == Find(p))//判断q和p的根是否相同
            {
                printf("YES\n");
            }
            else
            {
                printf("NO\n");
            }
        }
    }
    int cnt=0;//计算一共有多少个链
        for(int i=1;i<=6;i++)
        {
            if(pre[i] == i)
                cnt++;
        }
        printf("%d!!\n",cnt);
    return 0;
}

你可能感兴趣的:(CUIT-ACM 01-16 F)