题意:
给出类似剪刀石头布的相互克制关系,看是否有矛盾条件出现。经典题目,根据poj 1182“食物链”改编。
题解:
题面描述了一些生物之间的关系,不难会想到并查集。
但是生物关系不是确定的,所以要在描述关系的集合当中加入一些额外的参数。
因为只有三种生物,所以我们定义:
当sett[x]=y的情况下(即x与y有关系):
val[x]==val[y]相等说明x和y是同类
(val[x]-val[y]) % 3 = 1说明x克制y
(val[x]-val[y]) % 3 = -1 = 2说明y克制x
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int Max = 1000000;
int fat[Max], ran[Max];
void Init(int n)
{
for (int i = 0; i <= n; i++)
{
fat[i] = i;
ran[i] = 0;
}
return;
}
int Find(int x)
{
if (x == fat[x])
return fat[x];
int y = Find(fat[x]);
ran[x] = (ran[x] + ran[fat[x]]) % 3;
return fat[x] = y;
}
int Union(int typ, int x, int y)
{
int x1 = Find(x);
int y1 = Find(y);
if (x1 == y1)
{
if ((ran[x] - ran[y] + 3) % 3 == typ - 1)
return 0;
return 1;
}
fat[x1] = y1;
ran[x1] = (-ran[x] + typ - 1 + ran[y] + 3) % 3;
return 0;
}
int main()
{
int n, k, ans;
int typ, smt1, smt2;
scanf("%d %d", &n, &k);
Init(n);
ans = 0;
bool flag = true;
for (int i = 0; i<k; i++)
{
scanf("%d %d %d", &typ, &smt1, &smt2);
if (Union(typ, smt1, smt2) && flag) {
flag = false;
ans = i;
}
}
if (flag)
printf("-1
");
else
printf("%d
", (ans + 3) % 3 + 1);
return 0;
}