《扩展域并查集》

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;
}
View Code

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;
}
View Code

 

posted @ 2021-10-18 22:38  levill  阅读(41)  评论(0编辑  收藏  举报