参考:参考博客
#include <iostream>
#include <algorithm>
using namespace std;
const int maxn = 50010;
int n, m;
struct node
{
int x, y;
int rel;
node() {}
node(int _x, int _y, int _rel) : x(_x), y(_y), rel(_rel) {}
} a[maxn];
int father[maxn];
int relation[maxn];
int change(char c)
{
if (c == '=')
{
return 0;
}
else if (c == '<')
{
return 1;
}
else
{
return 2;
}
}
void init()
{
for (int i = 0; i <= n; i++)
{
father[i] = i;
relation[i] = 0;
}
}
int find(int x)
{
if (father[x] == x)
{
return x;
}
else
{
int tf = father[x];
father[x] = find(father[x]);
relation[x] = (relation[x] + relation[tf]) % 3;
return father[x];
}
}
bool unite(int x, int y, int ope)
{
int faX = find(x);
int faY = find(y);
if (faX != faY)
{
father[faY] = faX;
relation[faY] = ((3 - relation[y]) % 3 + ope - 1 + relation[x]) % 3;
}
else
{
int rex = (3 - relation[x]) % 3;
if ((rex + relation[y]) % 3 != ope)
{
return false;
}
}
return true;
}
int main()
{
while (scanf("%d%d", &n, &m) == 2)
{
init();
int l, r;
char oper;
for (int i = 1; i <= m; i++)
{
cin >> l >> oper >> r;
int ope = change(oper);
a[i] = node(l, r, ope);
}
int maxLine = 0; //产生矛盾的最大行数
int person = -1; //记录下裁判编号
int ans = 0; //判断有多少合法的裁判人选
for (int i = 0; i < n; i++) //枚举裁判
{
bool flag = false; //是否会产生矛盾
init();
for (int j = 1; j <= m; j++)
{
if (a[j].x == i || a[j].y == i) ///排除带i的边
{
continue;
}
if (!unite(a[j].x, a[j].y, a[j].rel))
{
maxLine = max(maxLine, j);
flag = true;
break; //如果这里不跳出循环,就会改变maxLine的值,也就是这里发生错误的情况下,就不能继续向下搜索
}
}
if (!flag)
{
ans++;
person = i;
}
}
if (ans == 1)
{
cout << "Player " << person << " can be determined to be the judge after " << maxLine << " lines" << endl;
}
else if (ans > 1)
{
cout << "Can not determine" << endl;
}
else
{
cout << "Impossible" << endl;
}
}
return 0;
}