POJ 2912 Rochambeau(枚举 + 并查集)
Solution
枚举每个人能否作为裁判,记录能作为裁判的人的个数,超过一个则为 Impossible,0 个则为不能确定。
记录最早判断裁判的轮次:
最晚出现自相矛盾的轮次。
代码
#include <algorithm>
#include <cmath>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <stdio.h>
#include <string.h>
#include <string>
#include <vector>
//#define int long long
#define lowbit(x) ((x) & (-x))
using namespace std;
typedef pair<int, int> pii;
typedef pair<long, long> pll;
typedef pair<double, int> pdi;
typedef double dd;
typedef long long ll;
const int MAXN = 510;
const int MAXM = 10010;
const dd eps = 1e-6;
const int inf = 0x3f3f3f3f;
const ll llinf = 0x3f3f3f3f3f3f3f3f;
struct TY{
int x, y;
char ch;
} a[2010];
int n, m, fa[MAXN], dis[MAXN];
int mod(int x){
return (x % 3 + 3) % 3;
}
int fd(int x)
{
if(x == fa[x])
return x;
int f = fd(fa[x]);
dis[x] = mod(dis[x] + dis[fa[x]]);
return (fa[x] = f);
}
bool un(int x, int y, int w)
{
int fx = fd(x), fy = fd(y);
if(fx == fy)
{
if (mod(dis[y] - dis[x]) != w)
return 0;
return 1;
}
fa[fy] = fx;
dis[fy] = mod(w - dis[y] + dis[x]);
return 1;
}
int main()
{
while (~scanf("%d%d", &n, &m))
{
if(m == 0 && n == 1)
{
printf("Player 0 can be determined to be the judge after 0 lines\n");
continue;
}
for (int i = 1; i <= m;i++)
scanf("%d%c%d", &a[i].x, &a[i].ch, &a[i].y);
int det = 0;
int lun = 0, id = -1;
for (int i = 0; i < n;i++)
{
bool ok = 1;
memset(dis, 0, sizeof(dis));
for (int j = 0; j < n;j++)
fa[j] = j;
for (int j = 1; j <= m;j++)
{
if(a[j].x == i || a[j].y == i)
continue;
int w = 0;
if(a[j].ch == '>')
w = -1;
else if(a[j].ch == '<')
w = 1;
if (!un(a[j].x, a[j].y, mod(w)))
{
lun = max(lun, j);
ok = 0;
break;
}
}
if(!ok)
continue;
det++, id = i;
}
// if(n == 1)
// lun = 0;
if (det < 1)
printf("Impossible\n");
else if(det > 1)
printf("Can not determine\n");
else
printf("Player %d can be determined to be the judge after %d lines\n", id, lun);
}
}