• POJ 1733 Parity game


    并查集

    首先将 sum[l, r] 的奇偶性转换成 sum[1, l - 1] 和 sum[1, r] 的奇偶性是否相同
    注意是 l - 1
    然后维护并查集,有边带权和扩展域两种做法

    边带权

    若两数奇偶性相同,边权为 0 ,若不同,边权为 1 ,然后异或处理即可

    #include <iostream>
    #include <cstdio>
    #include <cmath>
    #include <cstdlib>
    #include <algorithm>
    using namespace std;
    const int MAXN = 20005;
    int n, m, fa[MAXN], dis[MAXN], dat[MAXN], sub[MAXN], id[MAXN], tot;
    struct po{
    	int u, v, opt;
    }a[MAXN];
    char s[10];
    int find(int x) {
    	if(x != fa[x]) {
    		int t = find(fa[x]);
    		dis[x] ^= dis[fa[x]];
    		fa[x] = t;
    		return fa[x];
    	}
    	return fa[x];
    }
    int main() {
    	cin >> m >> n;
    	for(int i = 1; i <= n; i++) {
    		cin >> a[i].u >> a[i].v >> s;
    		if(s[0] == 'o') a[i].opt = 1;
    		else a[i].opt = 0;
    		++tot, sub[tot] = dat[tot] = a[i].u;
    		++tot, sub[tot] = dat[tot] = a[i].v;
    	}
    	sort(sub + 1, sub + 1 + tot);
    	tot = unique(sub + 1, sub + 1 + tot) - sub - 1;
    	for(int i = 1; i <= n * 2; i++) {
    		id[i] = lower_bound(sub + 1, sub + 1 + tot, dat[i]) - sub;
    	}
    	//for(int i = 1; i <= n * 2; i++) printf("%d %d
    ", dat[i], id[i]);
    	for(int i = 1; i <= tot; i++) fa[i] = i;
    	for(int i = 1; i <= n; i++) {
    		a[i].u = id[i * 2 - 1] - 1, a[i].v = id[i * 2];
    		int r1 = find(a[i].u), r2 = find(a[i].v);
    		//printf("%d %d
    ", a[i].u, a[i].v);
    		if(r1 != r2) {
    			fa[r1] = r2;
    			dis[r1] = a[i].opt ^ dis[a[i].u] ^ dis[a[i].v];
    		}else {
    			if((dis[a[i].u] ^ dis[a[i].v]) != a[i].opt) {printf("%d
    ", i - 1);return 0;}
    		}
    	}
    	/*for(int i = 1; i <= tot; i++) {
    		printf("%d %d %d
    ",i + 1, fa[i], dis[i]);
    	}*/
    	printf("%d
    ", n);
    	return 0;
    }
    

    扩展域

    #include <iostream>
    #include <cstdio>
    #include <cmath>
    #include <cstdlib>
    #include <algorithm>
    using namespace std;
    const int MAXN = 20005;
    int n, m, fa[MAXN], dat[MAXN], sub[MAXN], id[MAXN], tot;
    struct po{
    	int u, v, opt;
    }a[MAXN];
    char s[10];
    int find(int x) {
    	if(x != fa[x]) return fa[x] = find(fa[x]);
    	return fa[x];
    }
    void merge(int x, int y) {
    	int r1 = find(x), r2 = find(y);
    	if(r1 != r2){
    		fa[r1] = r2;
    	}
    }
    int main() {
    	cin >> m >> n;
    	for(int i = 1; i <= n; i++) {
    		cin >> a[i].u >> a[i].v >> s;
    		if(s[0] == 'o') a[i].opt = 1;
    		else a[i].opt = 0;
    		++tot, sub[tot] = dat[tot] = a[i].u;
    		++tot, sub[tot] = dat[tot] = a[i].v;
    	}
    	sort(sub + 1, sub + 1 + tot);
    	tot = unique(sub + 1, sub + 1 + tot) - sub - 1;
    	for(int i = 1; i <= n * 2; i++) {
    		id[i] = lower_bound(sub + 1, sub + 1 + tot, dat[i]) - sub;
    	}
    	tot++;
    	//for(int i = 1; i <= n * 2; i++) printf("%d %d
    ", dat[i], id[i]);
    	for(int i = 1; i <= tot * 2; i++) fa[i] = i;
    	for(int i = 1; i <= n; i++) {
    		a[i].u = id[i * 2 - 1] - 1, a[i].v = id[i * 2];
    		int u = a[i].u, v = a[i].v;
    		if(a[i].opt) {
    			if(find(u) == find(v)) {printf("%d
    ", i - 1); return 0;}
    			merge(u, v + tot);merge(v, u + tot);
    		}else {
    			if(find(u) == find(v + tot) || find(v) == find(u + tot)) {printf("%d
    ", i - 1);return 0;}
    			merge(u, v);merge(u + tot, v + tot);
    		}
    	}
    	/*for(int i = 1; i <= tot; i++) {
    		printf("%d %d %d
    ",i + 1, fa[i], dis[i]);
    	}*/
    	printf("%d
    ", n);
    	return 0;
    }
    
  • 相关阅读:
    UOS安装gitlab
    docker中连接sqlserver 2008R2(SP3) 失败解决方法
    AtCoder AGC020 E-Encoding Subsets
    CF1553H XOR and Distance
    CF1039E Summer Oenothera Exhibition
    HDOJ 6991 Increasing Subsequence
    HDOJ 6964 I love counting
    Topcoder 15279 SpanningSubgraphs
    全程NOIP计划 题目选做
    分层图总结
  • 原文地址:https://www.cnblogs.com/Mr-WolframsMgcBox/p/8585245.html
Copyright © 2020-2023  润新知