POJ 1182

  并查集应用,只要会做POJ2492,这道题也没什么问题了,也是利用偏移量解题,注意的是,为了方便起见,relation[x]=0表示x与x的根节点的关系是同类,relation[x]=1表示x被x的根节点吃,relation[x]=2表示x吃x的根节点。所以读入kind的时候应该改一下。另外,x吃x才算错,所以数据如1 5 5是正确的。有关偏移量,在POJ 2492的解题报告中有详细的说明,由于这道题POJ只有单组数据,所以while scanf()!=EOF应该去掉。

#include<stdio.h>
#define MAX_ANIMAL 50010
int get_root(int),parnt[MAX_ANIMAL],relation[MAX_ANIMAL];
void merge(int,int,int);
int main()
{
    int n,k;
    while(scanf("%d%d",&n,&k)!=EOF)
    {
    int i,ans=0;
    for(i=0;i<MAX_ANIMAL;i++)
    {
        parnt[i]=i;
        relation[i]=0;
    }
    for(i=0;i<k;i++)
    {
        int kind,a,b;
        scanf("%d%d%d",&kind,&a,&b);
        if(kind==1)
        kind=0;
        if(a>n||b>n)
        {
        ans++;
        }
        else if(a==b&&kind==2)
        {
        ans++;
        }
        else
        {
        int roota=get_root(a),rootb=get_root(b);
        if(roota!=rootb)
        {
            merge(a,b,kind);
        }
        else
        {
            if(kind!=((relation[a]+3-relation[b])%3))
            {
            ans++;
            }
        }
        }
    }
    printf("%d\n",ans);
    }
    return 0;
}
int get_root(int x)
{
    if (parnt[x]==x)
    return x;
    int tmp=get_root(parnt[x]);
    relation[x]= (relation[x]+relation[parnt[x]])%3;
    return parnt[x]=tmp;
}
void merge(int x,int y,int kind)
{
    int rootx=get_root(x),rooty=get_root(y);
    if(rootx==rooty)
    return ;
    relation[rooty]=(relation[x]+3-kind+3-relation[y])%3;
    parnt[rooty]=rootx;
}
posted @ 2012-08-04 16:47  等待电子的砹  阅读(225)  评论(0编辑  收藏  举报