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

来源:互联网 发布:windows snmp命令 编辑:程序博客网 时间:2024/05/22 00:51

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

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

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

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

代码:

#include <iostream>#include <cstdio>#include <algorithm>#include <string>#include <cstring>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");    }}
  • 所有的都要处理,但是在处理过程中就可以判断是否存在关系相同的
原创粉丝点击