POJ 2912 Rochambeau(枚举 + 并查集)

POJ 2912 Rochambeau(枚举 + 并查集)

vj链接

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);
	}
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值