数据结构算法——1084. 食物链

题目

在这里插入图片描述
输入
100 7
1 101 1
2 1 2
2 2 3
2 3 3
1 1 3
2 3 1
1 5 5

输出
3

思路

参考前一题1083. 小强的烦恼
这里的区别是tag多加了一种状态
在mod3下的x的tag后继数(0后继为1,1后继为2,2后继为3)说明y是x的食物链上层

代码

#include<iostream>
#include<map>

using namespace std;
struct dot
{
    int father;
    int tag;//tag大代表食物链上层
};
map<int,dot>m;

pair<int,int>find(int x)
{
    if(m[x].father == x)    return{x,0};
    pair<int,int>p = find(m[x].father);
    m[x].father = p.first;
    m[x].tag = (m[x].tag + p.second) % 3;
    return {m[x].father, m[x].tag};
}
//简单版
// int find(int x)
// {
//     while(m[x].father != x)
//         x = m[x].father;
//     return x;
// }

int getF(int x)
{
    find(x); return m[x].father;
}
void U(int x, int y, int v)
{
    find(x);find(y);
    int x_father = m[x].father;
    m[x_father].tag = (v + m[y].tag - m[x].tag + 3) % 3;
    m[x_father].father = m[y].father;
}
int question(int x, int y)
{
    if(getF(x) == getF(y))
    {
        if(m[x].tag == m[y].tag)    return 0;//同类
        if((m[x].tag + 1)%3  == m[y].tag)   return 2;//Y吃X
        return 1;//X吃Y
    }
    return -1;//说明没确定关系
}

int main()
{
    int N,K;
    cin >> N >> K;
    for(int i = 1; i <= N; i++)
    {
        m[i].father = i;
        m[i].tag = 0;
    }
    int count = 0;
    for(int i = 0; i < K; i++)
    {
        int order, x, y;
        cin >> order >> x >> y;
        if(x > N || y > N)
        {    
            count++;
            continue;
        }
        int relation = question(x, y);
        switch(order)
        {
        case 1:
            if(relation == -1)
                U(x, y, 0);
            else if(relation != 0)
                count++;
        break;

        case 2:
            if(relation == -1)
                U(x, y, 1);//x是y的食物链上层
            else if(relation != 1)count++;
        break;    
        }
    }
    cout << count << endl;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值