《扩展域并查集》
P1892 [BOI2003]团伙:
遵循,敌人的敌人就是朋友的原则,合并敌人的敌人和本身。然后这里其实是大像小合并,因为这样才能保证根都在n内。
// Author: levil #include<bits/stdc++.h> using namespace std; typedef long long LL; typedef unsigned long long ULL; typedef pair<int,int> pii; const int N = 1e7 + 5; const int M = 2e4 + 5; const double eps = 1e-10; const LL Mod = 1e9 + 7; #define pi acos(-1) #define INF 1e18 #define dbg(ax) cout << "now this num is " << ax << endl; inline LL read() { LL f = 1;LL x = 0;char c = getchar(); while(c < '0' || c > '9') {if(c == '-') f = -1;c = getchar();} while(c >= '0' && c <= '9'){x = (x<<1)+(x<<3)+(c^48);c = getchar();} return x*f; } inline long long ADD(long long x,long long y) {return (x + y) % Mod;} inline long long DEC(long long x,long long y) {return (x - y + Mod) % Mod;} inline long long MUL(long long x,long long y) {return x * y % Mod;} int fa[2005]; int Find(int x) {return x == fa[x] ? x : fa[x] = Find(fa[x]);} void Union(int x,int y) { int xx = Find(x),yy = Find(y); if(xx != yy) fa[xx] = yy; } void solve() { int n;n = read(); for(int i = 1;i <= 2 * n;++i) fa[i] = i; int m;m = read(); while(m--) { string s;cin >> s; int x,y;x = read(),y = read(); if(s[0] == 'F') Union(x,y); else { Union(y + n,x); Union(x + n,y); } } int ans = 0; for(int i = 1;i <= n;++i) if(fa[i] == i) ans++; printf("%d\n",ans); } int main() { solve(); // system("pause"); return 0; }
Rochambeau:POJ 2912:
这题,我们对每个人的每个值都来一个并查集,做一个猜想。
每个人只有三种身份:剪刀或者石头或者布。
如果某次合并之后两个不同的集合根不一样,就说明出现了矛盾。
// Author: levil #include<iostream> #include<stdio.h> #include<queue> #include<algorithm> #include<math.h> #include<stack> #include<map> #include<limits.h> #include<vector> #include<string.h> #include<string> using namespace std; typedef long long LL; typedef unsigned long long ULL; typedef pair<int,int> pii; const int N = 1e5 + 5; const int M = 2e4 + 5; const double eps = 1e-10; const LL Mod = 1e9 + 7; #define pi acos(-1) #define INF 1e18 #define dbg(ax) cout << "now this num is " << ax << endl; inline LL read() { LL f = 1;LL x = 0;char c = getchar(); while(c < '0' || c > '9') {if(c == '-') f = -1;c = getchar();} while(c >= '0' && c <= '9'){x = (x<<1)+(x<<3)+(c^48);c = getchar();} return x*f; } inline long long ADD(long long x,long long y) {return (x + y) % Mod;} inline long long DEC(long long x,long long y) {return (x - y + Mod) % Mod;} inline long long MUL(long long x,long long y) {return x * y % Mod;} int n,m,fa[N];//shitou ,jiandao ,bu struct Query{int x,y,id;}p[2005]; int Find(int x) {return x == fa[x] ? x : fa[x] = Find(fa[x]);} bool Union(int x,int y,int id) { if(id == 0) { int x1 = Find(x),y3 = Find(y + n * 2); if(x1 != y3) fa[x1] = y3; int x2 = Find(x + n),y1 = Find(y); if(x2 != y1) fa[x2] = y1; int x3 = Find(x + n * 2),y2 = Find(y + n); if(x3 != y2) fa[x3] = y2; } else if(id == 1) { int x1 = Find(x),y2 = Find(y + n); if(x1 != y2) fa[x1] = y2; int x2 = Find(x + n),y3 = Find(y + n * 2); if(x2 != y3) fa[x2] = y3; int x3 = Find(x + n * 2),y1 = Find(y); if(x3 != y1) fa[x3] = y1; } else { int x1 = Find(x),y1 = Find(y); if(x1 != y1) fa[x1] = y1; int x2 = Find(x + n),y2 = Find(y + n); if(x2 != y2) fa[x2] = y2; int x3 = Find(x + n * 2),y3 = Find(y + n * 2); if(x3 != y3) fa[x3] = y3; } if(Find(x) == Find(x + n) || Find(x) == Find(x + 2 * n) || Find(x + n) == Find(x + 2 * n)) return false; if(Find(y) == Find(y + n) || Find(y) == Find(y + 2 * n) || Find(y + n) == Find(y + 2 * n)) return false; return true; } void solve() { while(~scanf("%d %d",&n,&m)) { for(int i = 1;i <= m;++i) { string s;cin >> s; int x = 0,y = 0,f = 0; for(int j = 0;j < s.size();++j) { char v = s[j]; if(v >= '0' && v <= '9') { if(f == 0) x = x * 10 + v - '0'; else y = y * 10 + v - '0'; } else { if(v == '<') p[i].id = 0; else if(v == '>') p[i].id = 1; else p[i].id = 2; f = 1; } } p[i].x = ++x,p[i].y = ++y; } int cnt = 0,pos = 0,ans; for(int i = 1;i <= n;++i) { for(int j = 1;j <= n * 3;++j) fa[j] = j; int f = 0; for(int j = 1;j <= m;++j) { if(p[j].x == i || p[j].y == i) continue; if(!Union(p[j].x,p[j].y,p[j].id)) { f = 1; pos = max(pos,j); break; } } if(f == 0) cnt++,ans = i; } if(cnt == 0) printf("Impossible\n"); else if(cnt > 1) printf("Can not determine\n"); else printf("Player %d can be determined to be the judge after %d lines\n",ans - 1,pos); } } int main() { solve(); system("pause"); return 0; }