题解:P10686 Rochambeau
思路
作为经典的并查集问题,按照剪刀石头布分为三类,但是本题关键并不在于每个人属于哪一类,而是在于两个人的关系。这个关系我们可以用边权来记,由于规则分为平局和非平局,所以边权很容易用
for (int i = 1; i <= m; i++) {
cin >> pl[i].a >> pl[i].c >> pl[i].b;
if (pl[i].c == '>') {
swap(pl[i].a, pl[i].b);//交换顺序
}
}
所以对于每个人,先初始化,(
for (int i = 1; i <= n; i++)f[i] = i;
memset(d, 0, sizeof(d));//d表示到根节点的距离
当我们考虑每组数据的时候,由于
并查集函数
int dfs(int x) {
if (x == f[x])return f[x];
int t = dfs(f[x]);
d[x] = d[x] + d[f[x]];
return f[x] = t;
}
下面讨论对每局游戏的判断,假设是
int x1=pl[i].a, x2=pl[i].b, dis = 0;
char c=pl[i].c;
if (x1 == k || x2 == k)continue;//裁判参与就不判断,因为一定不矛盾
int a = dfs(x1), b = dfs(x2);
if (c == '<'||pl[i].c=='>')dis = 1;
if (c == '=')dis = 0;
下面判断两种情况,就是两个人在不在一个集合以内
if (a == b)
{
if (((d[x1] - d[x2]) % 3 + 3) % 3 != dis){
ok = false;
tp = min(tp, i);//记录判断裁判的位置
}
}
else
{
f[a] = b;
d[a] = ((d[x2] - d[x1] + dis) % 3 + 3) % 3;
}
代码
#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;
const int N = 505, M = 2005;
int f[N], d[N];
int cnt = 0, n = 0, m = 0;
struct node {
int a, b;
char c;
}pl[M];
int dfs(int x) {
if (x == f[x])return f[x];
int t = dfs(f[x]);
d[x] = d[x] + d[f[x]];
return f[x] = t;
}
int main(void) {
while (cin >> n >> m) {
int cnt = 0, num = 0, tp = 0, pos = 0;
if (n == 1 && m == 0) {
num = 0, pos = 0;
}
for (int i = 1; i <= m; i++) {
cin >> pl[i].a >> pl[i].c >> pl[i].b;
if (pl[i].c == '>') {
swap(pl[i].a, pl[i].b);
}
}
for (int k = 0; k < n; k++) {
tp = 2001;
for (int i = 0; i < n; i++)f[i] = i;
memset(d, 0, sizeof(d));
bool ok = true;
for (int i = 1; i <= m; i++) {
int x1=pl[i].a, x2=pl[i].b, dis = 0;
char c=pl[i].c;
if (x1 == k || x2 == k)continue;
int a = dfs(x1), b = dfs(x2);
if (c == '<'||c=='>')dis = 1;
if (c == '=')dis = 0;
if (a == b) {
if (((d[x1] - d[x2]) % 3 + 3) % 3 != dis) {
ok = false;
tp = min(tp, i);
}
}
else {
f[a] = b;
d[a] = ((d[x2] - d[x1] + dis) % 3 + 3) % 3;
}
}
if (tp == 2001) cnt++, num = k;
else pos = max(pos, tp);
}
if (cnt == 0) {
cout << "Impossible" << endl;
}
else if (cnt > 1) {
cout << "Can not determine" << endl;
}
else {
cout << "Player " << num << " can be determined to be the judge after " << pos << " lines\n";
}
}
return 0;
}