poj 1182 食物链

经典经典并查集!!!!

强烈建议自己写一遍,真是。。

其实重点就是偏移量的更新。ps可以用向量解。

传送传送

推荐并查集讲得很好玩的

#include<cstdio>
#include<iostream>
#include<algorithm>

using namespace std;
 int n,k,i,num,r1,r2,d,x,y;
 /*relaton = 0,同类;
relation=1,被父节点吃;
relationg=2,吃父节点;*/ 
struct node
{

 int parent;
 int relation;
}p[50010];

int find(int x)

{
    int t;
    if(p[x].parent==x) return x;
    else
    {
        t=p[x].parent; 
        p[x].parent=find(t);
        p[x].relation=(p[t].relation+p[x].relation)%3;
}

    return p[x].parent;
    /*说明:
    在查找之前,x的父亲节点是fx;假设p[x].relation=0(即r和父亲同类),
    p[x].relation=1(也就是fx被fxx吃;经过路径压缩,r的父亲节点变为fxx;
    所以更新关系应该为up;*/ 

}

void join()

{
    p[r1].parent=r2; 
    p[r1].relation=(3+d-1+p[y].relation-p[x].relation)%3;
    /*if p[x].relation=0  p[y].relation=1(即rooty吃y),则有:\
        1>输入d=1时,可以推出rooty吃rootx,
        即p[rooty].relation=2;
        2>输入d=2时,即输入的x吃y,可以推出rooty与rootx是同类(因为rooty吃y,x吃y,
        则rooty与x是同类,又rootx与x是同类),即p[rooty].relation=0;
        +3是为了判负数;*/

}

int main()

{
    scanf("%d%d",&n,&k);
    for(i=1;i<=n;i++)//初始化 
    {
     p[i].parent=i;
     p[i].relation=0;
    }
    num=0;
    while(k--)
    {
     scanf("%d%d%d",&d,&x,&y);
     if(x>n||y>n||(d==2&&x==y))  num++;
    else
     {
         r1=find(x);
        r2=find(y);
         if(r1!=r2)
        join();
        else 
         {
             if(d==1&&p[x].relation!=p[y].relation) num++;
             else if(d==2&&(p[x].relation-p[y].relation+3)%3!=1) num++;
         }
     }
    }
    printf("%d\n",num);
    return 0;

}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值