并查集-A Bug's Life(poj2492)

题意:
给出N条虫子,让a和b交配,
给出M对a和b交配后问,
有没有性别矛盾的虫子,
即和一只虫子和男的交配完之后又和女的交配
题解:
1.压缩路径关系转化,r[x] = (r[x]+r[f[x]])%2,很好理解//r[x]表示x和fx的关系,0同性,1异性
若x和fx为同性(r[x] = 0):
    fx和ffx为异性(r[fx] = 1),则x和ffx为异性,x和ffx的关系r[x]更新为0+1=1
    fx和ffx为同性(r[fx] = 0),则x和ffx为同性,x和ffx的关系r[x]更新为0+0=0
若x和fx为异性(r[x] = 1):
    fx和ffx为异性(r[fx] = 1),则x和ffx为同性,x和ffx的关系r[x]更新为(1+1)%2=0
    fx和ffx为同性(r[fx] = 0),则x和ffx为异性,x和ffx的关系r[x]更新为1+0=1
2.并查集联合若父节点相同
if(r[x] == r[y]) mark = true; //x和y性别不同,因为父节点相同,所以x,y和父节点关系相同就是假话
3.并查集联合若父节点不同,这句话为真话,把fy的父节点设置为fx
f[fy] = fx;
r[fy] = (1+r[x]-r[y])%2;

   

 #include <iostream>
    #include <cstdio>
    #include <cstring>
    using namespace std;
    int f[2010], r[2010];//f数组指向与它交配的bug,初始化自交
    //r表示他的父节点与它是同性还是异性,0同性,1异性
    bool mark;
    int find_head(int x)
    {
        int fx = x;
        if(x != f[x])
        {
            fx = find_head(f[x]);
            r[x] = (r[x]+r[f[x]])%2;
            f[x] = fx;
        }
        return fx;
    }
    void union_set(int x, int y)
    {
        int fx = find_head(x);
        int fy = find_head(y);
        if(fx == fy)//父亲结点相同
        {
            if(r[x] == r[y]) //x和y性别不同,因为父节点相同,所以x,y和父节点关系相同就是假话
            {
                mark = true;
            }
        }
        else//父亲结点不同,这句话为真话,把fy的父节点设置为fx
        {
            f[fy] = fx;
            r[fy] = (1+r[x]-r[y])%2;
        }
    }
    int main()
    {
        int t;
        cin>>t;
        for(int i = 1; i <= t; i++)
        {
            int n, m;
            mark = false;
            scanf("%d%d", &n,&m);
            memset(r, 0, sizeof(r));
            for(int k = 1; k <= 2010; k++)
            {
                f[k] = k;
            }
            for(int j = 1; j <= m; j++)
            {
                int x, y;
                scanf("%d%d", &x,&y);
                if(!mark)
                {
                    union_set(x, y);
                }
            }
            cout<<"Scenario #"<<i<<":"<<endl;
            if(mark) cout<<"Suspicious bugs found!"<<endl;
            else cout<<"No suspicious bugs found!"<<endl;
            cout<<endl;
        }
    }

猜你喜欢

转载自blog.csdn.net/weixin_43863650/article/details/84786149