题目链接在这里
题目大意
有n个学生玩剪子包袱锤,其中有一个人是可以在剪子包袱锤中随意出,另外n-1个学生被分为3组,每一组只能固定出一个固定的(三组出的互不相同)。有m轮比赛。问经过m轮比赛后能不能判断出来谁是裁判。
想法
这是一个带权并查集问题,除去裁判之外有3类学生。我们可以在n个学生中枚举谁是裁判,比如说1是裁判,那么在m轮比赛里我们就忽略有关学生1的比赛,看剩下的有没有矛盾(比如0赢了2,后来2又赢了0),如果没有矛盾的话就说明学生1就是裁判,如果有矛盾的话,我们就记录下来它在第cn次比赛出现矛盾(代表着在第cn轮比赛中判断出来的1不是裁判)。如果仅有一个裁判的话,我们就取各cn中的最大值作为答案输出。
代码如下
#include <stdio.h>
#include <string.h>
#include <iostream>
#include <algorithm>
#define clr(x) memset(x, 0, sizeof(x))
#define rep(i, x) for(int i = 0; i < x; ++i)
using namespace std;
const int MaxN = 510;
const int MaxM = 2010;
struct Node{
int x, y;
char ch;
}node[MaxM];
int n, m;
int par[MaxN], Rank[MaxN];
void init(){
rep(i, MaxN) par[i] = i;
clr(Rank);
}
int Find(int x){
if(x == par[x]) return x;
int tmp = par[x];
par[x] = Find(par[x]);
Rank[x] = (Rank[x] + Rank[tmp]) % 3;
return par[x];
}
bool unite(int x, int y, int n){
int fx = Find(x);
int fy = Find(y);
if(fx == fy){
if(n && (Rank[y] + 1) % 3 != Rank[x]) return false;
if(!n && Rank[x] != Rank[y]) return false;
return true;
}
par[fx] = fy;
Rank[fx] = (n + Rank[y] - Rank[x] + 3) % 3;
return true;
}
void solve(){
int cnt[MaxN];
clr(cnt);
rep(pe, n){
//cout << pe << "是裁判" << endl;
init();
int flag;
rep(i, m){
if(node[i].x == pe || node[i].y == pe) continue;
if(node[i].ch == '=')
flag = unite(node[i].x, node[i].y, 0);
else
flag = unite(node[i].x, node[i].y, 1);
/**************************************************************/
//printf("Rank[%d]:%d, Rank[%d]:%d\n", node[i].x, Rank[node[i].x], node[i].y, Rank[node[i].y]);
if(!flag){
cnt[pe] = i + 1; //第i局判断出来pe不是裁判
break;
}
}
}
int num = 0; //计数有多少个人被判断为裁判
int p;
rep(i, n)
if(cnt[i] == 0){
++num;
p = i;
}
if(num > 1)
cout << "Can not determine" << endl;
if(num == 1){
int Max = 0;
rep(i, n) Max = max(Max, cnt[i]);
cout << "Player " << p << " can be determined to be the judge after " << Max << " lines" << endl;
}
if(num == 0)
cout << "Impossible" << endl;
}
int main(){
ios::sync_with_stdio(false);
while(cin >> n >> m){
rep(i, m){
cin >> node[i].x >> node[i].ch >> node[i].y;
if(node[i].ch == '>'){
node[i].ch = '<';
node[i].x ^= node[i].y;
node[i].y ^= node[i].x;
node[i].x ^= node[i].y;
}
}
solve();
}
return 0;
}