1. 程式人生 > 其它 >小x玩遊戲

小x玩遊戲

題目大意

今天,小 x 因為太無聊,就在玩遊戲。

這個遊戲有兩個隊伍,然後他們在遊戲裡面打來打去。

但小 x 遇到了難題。他不知道自己的隊友是誰。他只知道總共有兩個隊伍,每隊有 \(n\) 個人和很多組擊殺情況。

他想問你,現在他能否知道兩個隊伍分別有誰。

你可以幫助小 x 嗎?

解題思路

並查集水題。

對名字進行雜湊,或者用 map

\(x+2*n\)\(x\) 的敵人,

\(x\)\(y\) 是敵人,即表示為 \(fa[find(a + 2 * n)] = find(b),fa[find(b + 2 * n)] = find(a)\),因為敵人的敵人是朋友嘛。

最後判斷是否有矛盾即可。

考場判斷寫錯,慘丟 \(30pts\),啊!

AC CODE

#include <bits/stdc++.h>
using namespace std;

#define int long long

const int _ = 200007;

const int base = 233;

const int mod = 1e9 + 7;

int T, n, m;

int fa[_];

int k, f[_];

map<long long, int> q;

int sm[_];

void init()
{
	for(int i = 1; i <= k; ++i) q[f[i]] = 0;
	k = 0;
	memset(sm, 0, sizeof sm);
	for(int i = 1; i < _; ++i) fa[i] = i;
}

int find(int x)
{
	return fa[x] == x ? x : fa[x] = find(fa[x]);
}

char c[15];

signed main()
{
//	freopen("game.in", "r", stdin);
//	freopen("game.out", "w", stdout);
	scanf("%lld", &T);
	while(T--)
	{
		int ans = 0;
		scanf("%lld%lld", &n, &m);
		init();
		for(int i = 1; i <= m; ++i)
		{
			scanf("%s", c);
			int a, b;
			int x = 0;
			for(int j = 0, len = strlen(c); j < len; ++j)
			{
				x = (x * base % mod + (int)(c[j] - 'a' + 1)) % mod;
			}
			if(!q[x])
			{
				q[x] = ++k;
				f[k] = x;
				a = k;
			}
			else
			{
				a = q[x];
			}
			scanf("%s", c);
			x = 0;
			for(int j = 0, len = strlen(c); j < len; ++j)
			{
				x = (x * base % mod + (int)(c[j] - 'a' + 1)) % mod;
			}
			if(!q[x])
			{
				q[x] = ++k;
				f[k] = x;
				b = k;
			}
			else
			{
				b = q[x];
			}
			fa[find(a + 2 * n)] = find(b);
			fa[find(b + 2 * n)] = find(a);

		}
		if(2 * n > k)
		{
			puts("NO");
			continue;
		}
		for(int i = 1; i <= n * 2; ++i)
			sm[find(i)]++;
		bool flag = 0;
		for(int i = 1; i <= n * 2; ++i)
		{
			if(sm[i] == n)
			{
				printf("YES\n");
				flag = 1;
				break;
			}
		}
		if(!flag) printf("NO\n");
	}
}

本文來自部落格園,作者:蒟蒻orz,轉載請註明原文連結:https://www.cnblogs.com/orzz/p/15368505.html