A Bug's Life——带权并查集

题目链接

题意:

有N个虫子。科学家认为只有两只虫子不同性别时,才会发生关系。现在给你M个关系,让你判断是否存在同性恋

题解:

d【i】表示 i到根节点的距离 (即同性,异性的关系)

如果x,y在一个集合,并且他们是同性,那么就存在bug

如果 x,y不在一个集合,需要进行集合合并

先让fx指向fy 即 f[fy]=fx;

因为题目给定的 x,y都是异性关系,所以d[x]+d[fx]=d[y]+1  

 

代码:

 

#include<iostream>
#include<stdio.h>
#include<math.h>
#include<algorithm>
#include<vector>
using namespace std;
typedef long long ll;
const int maxn = 2e5+7;
int f[maxn],d[maxn];
int n,m;
int Find(int x)
{
    if(f[x]==x)return x;
    int root=Find(f[x]);
    d[x]=(d[x]+d[f[x]])%2;
    return f[x]=root;
}

int main()
{
    int t;
    scanf("%d",&t);
    int Case=1;
    while(t--)
    {
        scanf("%d%d",&n,&m);
        for(int i=0; i<=n; i++)f[i]=i,d[i]=0;
        int flag=1;
        while(m--)
        {
            int x,y;
            scanf("%d%d",&x,&y);
            int fx=Find(x);
            int fy=Find(y);
            if(fx==fy)
            {
                if(d[x]==d[y])
                {
                    flag=0;
                }
            }
            else
            {
                f[fx]=fy;
                d[fx]=(d[y]+1-d[x])%2;  ///题目给的x,y为异性  所以d[x]+d[fx]=d[y]+1;
            }
        }
        printf("Scenario #%d:\n",Case++);
        if(flag)
        {
            printf("No suspicious bugs found!\n");
        }
        else
        {
            printf("Suspicious bugs found!\n");
        }
        printf("\n");
    }

    return 0;
}
View Code

 

posted @ 2019-10-01 11:28  。小姜  阅读(145)  评论(0编辑  收藏  举报