题目
输入
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;
}