zoukankan      html  css  js  c++  java
  • 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;
    }
    
  • 相关阅读:
    Python3之命令行参数处理
    基于 Laradock 环境 Project 的总结
    Typora功能新发现-自动复制图片到指定目录下
    ubuntu 18.04 设置静态ip方法
    vscode 同时编辑多处,多个光标 快捷键
    nginx和ftp搭建图片服务器
    Centos 6.5出现yum安装慢的情况
    Linux中的CentOS 6克隆之后修改
    springMVC-文件上传CommonsMultipartFile
    Spring和mybatis整合 org.mybatis.spring.mapper.MapperScannerConfigurer
  • 原文地址:https://www.cnblogs.com/Mr-WolframsMgcBox/p/8585245.html
Copyright © 2011-2022 走看看