A Bug‘s Life HDU - 1829(种类并查集基础题)

题目思路

看完题目其实就能知道是挺裸的种类并查集

以下是个人对种类并查集的理解:
种类并查集是并查集的一种延申应用
如果并查集表示的关系是亲戚的亲戚是亲戚
那么种类并查集表示的关系就是敌人的敌人是朋友
种类并查集就是将多种类型的人之间的关系用数组存下来
大小一般是普通并查集的多倍
每个长度为n的区间表示一个种类
每次记录关系的时候是对不同区间的点做操作

这题还要注意最后输出要换两次行

ac代码

 #include <stdio.h>
#include <iostream>
#include <algorithm>
#include <math.h>
#include <string.h>
#include <vector>
#include <stack>
#include <queue>
#include  <map>
#include <set>
#include <utility>
#define pi 3.1415926535898
#define ll long long
#define lson rt<<1
#define rson rt<<1|1
#define eps 1e-6
#define ms(a,b) memset(a,b,sizeof(a))
#define legal(a,b) a&b
#define print1 printf("111\n")
using namespace std;
const int maxn = 1e6+5;
const int inf = 0x3f3f3f3f;
const ll llinf = 0x3f3f3f3f3f3f3f3f;
const ll mod = 1000000007;
//998244353

int f[maxn],flag;
int n,m;

int findx(int x)
{
    return f[x]==x?f[x]:f[x]=findx(f[x]);
}

void join(int x,int y)
{
    int r1=findx(x);
    int r2=findx(y);
    if(r1!=r2)
    {
        f[r1]=r2;
    };
}

bool uis(int x,int y)
{
    return(findx(x)!=findx(y));
}
int main()
{
    int t,ce=0;
    scanf("%d",&t);
    while(t--)
    {

        scanf("%d%d",&n,&m);
        for(int i=1;i<=2*n;i++)f[i]=i;
        flag=0;
        for(int i=1;i<=m;i++)
        {
            int x,y;
            scanf("%d%d",&x,&y);

            if(uis(x,y)&&uis(x+n,y+n))
            {
                join(x,y+n);
                join(x+n,y);
            }else
                flag=1;
        }
        printf("Scenario #%d:\n",++ce);
        if(flag==1)
        {
            printf("Suspicious bugs found!\n\n");
        }else
        {
            printf("No suspicious bugs found!\n\n");
        }
    }

}

你可能感兴趣的:(A Bug‘s Life HDU - 1829(种类并查集基础题))