HDU 1829 A Bug's Life(基础种类并查集)

来源:互联网 发布:海奇软件app 编辑:程序博客网 时间:2024/05/18 12:37

题目分析

基础的种类并查集,一直想写,但是苦于不会,今天找了个简单的练手。种类并查集除了需要维护fa[]数组,同时还要维护关系数组,这里面只有2种关系,一种是互斥,一种是不互斥,这样已经很明显了,我们用re数组中的数字来表示与根的关系,为0是与根互斥,为1与根不互斥,这样我们还需要在状态压缩的时候同样维护re数组,这样就做出来了。

#include <cstdio>#include <cstring>#include <iostream>#include <algorithm>using namespace std;const int maxn = 2005;int fa[maxn],re[maxn];  //父节点数组,关系数组bool flag;  //用来表示是否有bug存在int Find(int x)  //状态压缩{    if(fa[x] == x) return fa[x];    int temp = Find(fa[x]);    re[x] = (re[x] + re[fa[x]])&1;    fa[x] = temp;    return fa[x];}void Union(int x,int y){    int xx = Find(x);    int yy = Find(y);    if(xx == yy){     //属于同一个根        if(re[x] == re[y])  //2个bug原来的关系是互斥的,但是现在给出的关系是不互斥,很明显矛盾            flag = true;        return ;    }    fa[xx] = yy;    re[xx] = (re[x] + re[y] + 1)&1;  //推出2个根节点的关系}int main(){    int T;    scanf("%d", &T);    for(int kase = 1; kase <= T; kase++)    {        int n,m,x,y;        scanf("%d%d", &n, &m);        for(int i = 1; i <= n; i++)        {            fa[i] = i;            re[i] = 0;        }        flag = false;        for(int i = 1; i <= m; i++)        {            scanf("%d%d", &x, &y);            if(flag) continue;   //已经有bug存在,接下来的就不用判断了            Union(x,y);        }        printf("Scenario #%d:\n", kase);        if(flag) printf("Suspicious bugs found!\n\n");        else printf("No suspicious bugs found!\n\n");    }    return 0;}
0 0
原创粉丝点击