POJ 1182 食物链

走你:http://poj.org/problem?id=1182

详情写在代码里了。有疑问请评论


#include <stdio.h>
#include <algorithm>
#include <string.h>
#define MAXN 50010
using namespace std;
int r[MAXN],k,lie,f[MAXN],n;
void init()
{
    int i;
    //printf("init is right\n");
    for(i=1; i<=n; i++)
    {
          /*r[]表示每个节点与其对应的根节点之间的关系,
          0表示同类
          1表示被父节点吃
          2表示吃父节点*/
        f[i] = i;   //父节点一开始全是自己
        r[i] = 0;   //自己跟自己一定是同类吧
    }
}
int find_father(int x)
{
    if(x == f[x])
        return x;
    int t= f[x];                //记录x的父节点
    f[x] = find_father(f[x]);   //找到X的祖宗节点
    r[x] = (r[x]+r[t])%3;       //更新 x 与父节点之间的关系
    /*
        我们假设 x 与 y的关系r1,y 与 z关系r2

                 x 与 z的关系为 (r1+r2)%3
    */
    return f[x];
}
void uninon(int x,int y,int d)
{
    int fx= find_father(x);
    int fy= find_father(y);

    f[fy]= fx;
    r[fy]= (3-r[y]+(d-1)+r[x])%3;

    /*fx为x的根,fy为y的根
      合并时要把fx设置为fy的父节点

      fy  对 y的关系为  (3-r[y])%3
      y   对 x的关系为  d-1
      x   对 fx 的关系  r[x]

      所以fy 对应fx的关系为(3-r[y]+r[x]+d-1)%3
    */
}
int main()
{
    scanf("%d %d",&n,&k);//带权并查集  这题 的坑点在这,他不用多组测试数据
    init();
    lie=0;
    int op,x,y;
    for(int i=0; i<k; i++)
    {
        //printf("lie is %d\n",lie);
        scanf("%d %d %d",&op,&x,&y);

        if(x>n||y>n||(op==2 && x==y))
            lie++;
        else if(find_father(x) == find_father(y))
        {
            if(op==1 && r[x]!=r[y] )
                lie++;
            if(op==2 && (r[x]+1)%3 !=r[y])
                lie++;
        }
        else uninon(x,y,op);
    }
    printf("%d\n",lie);
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值