1. 程式人生 > >並查集-A Bug's Life(poj2492)

並查集-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;
        }
    }