小x玩遊戲
阿新 • • 發佈:2021-10-05
題目大意
今天,小 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