poj2492(并查集---类似“食物链”)

http://poj.org/problem?id=2492(poj 2492 点击打开题目链接)

思路:不同类的合并树,更新关系。

分析:和poj1703很类似,都是“食物链”的简化版,这个题没出来的原因还是没理解透。如果属于同一颗树,说明可以判断两者之间的关系,但是不能说明是同性,只有既属于同一棵树,又关系相同,才能说明是同性,在输入的过程中就可以判断了,而不需要把所有的都存下来再遍历判断(但是这里不是很懂啊)。

注意:这种输入的两个是不同类的,感觉可以套模板了。

代码:

#include 
#include 
#include 
#include 
#include 

using namespace std;

const int maxn = 2000 + 10;
int father[maxn];
int rank[maxn];

int n,m;

void init()
{
    for(int i = 0; i <= n; i++)
    {
        father[i] = i;
    }

    memset(rank,0,sizeof(rank));
}


int find(int x)
{
    if(x == father[x])
        return x;
   //这个地方注意,自己写的时候没写出来
    int y = father[x];//y是x的父亲,y是父节点,不是根节点
    father[x] = find(y);
    rank[x] = (rank[x] + rank[y]) % 2;//这里可以记住,以后直接用
    return father[x];
}

void unin(int a,int b)
{
    int fa = find(a);
    int fb = find(b);

    father[fa] = fb;
    //记住直接用
    rank[fa] = (rank[a] + 1 + rank[b]) % 2;

}


int main()
{
    int t,a,b,ans = 0;
    scanf("%d",&t);
    while(t--)
    {
        scanf("%d%d",&n,&m);
        init();
        bool isok = true;
        while(m--)
        {
            scanf("%d%d",&a,&b);
            if(find(a) == find(b))
            {//属于同一颗树,并且关系相同
                if(rank[a] == rank[b])
                {
                    isok = false;
                }

            }
            else if(find(a) != find(b))
            {
                unin(a,b);
            }

        }



        printf("Scenario #%d:\n",++ans);

        if(!isok)
            printf("Suspicious bugs found!\n");
        else
            printf("No suspicious bugs found!\n");
        if(t)
            printf("\n");
    }
}
  • 所有的都要处理,但是在处理过程中就可以判断是否存在关系相同的

你可能感兴趣的:(并查集)