POJ 1703 Find them, Catch them 并查集
2016-04-03 01:38
447 查看
原题见POJ 1703
N个人,M种输入,要么是声明两者不是同伙,要么是询问两者是否是同伙。思路
年幼不懂事,看着紫书上的秩做的,今天重新思考一番,其实原理和积木移动的想法如出一辙。把人当作积木,可以相互堆叠,a[i]为积木i底下的积木的个数(不严格,也可以是和这个数同奇偶的数字,在每次get累加路径上所有的a才能得到),p[i]为这堆积木最低端的积木编号。初始a[i]=0,p[i]=i.
声明操作:将i所在的积木堆整个移动到j所在的积木堆上方。同时改变a[p[i]]的值,使得get操作之后a[i]和a[j]不同奇偶(不是同伙)。再将p[p[i]]指向p[j]。
询问操作:get操作之后p[i]==p[j]时,i和j才具有可比性(比较的传递性),a[i]和a[j]同奇偶才是同伙,否则不是。
代码
#include <cstdio> #include <iostream> #include <cstring> #include <queue> #include <algorithm> #include <cmath> using namespace std; #define N 100100 int n, m, p , a ; int get(int x){ if(x != p[x]){ int t = get(p[x]); a[x] += a[p[x]]%2; p[x] = t; } return p[x]; } int main() { int T; scanf("%d", &T); while(T--){ scanf("%d%d", &n, &m); char com[10]; int u, v; for(int i = 0;i < n;i++){ p[i] = i; a[i] = 0; } for(int i = 0;i < m;i++){ scanf("%s%d%d", com, &u, &v); u--; v--; get(u); get(v); //先get一下,得到u和v的团长 if(com[0] == 'A'){ if(p[u] != p[v]) printf("Not sure yet.\n"); else if(a[u] % 2 == a[v] % 2) printf("In the same gang.\n"); else printf("In different gangs.\n"); } else{ a[p[v]] %= 2; a[p[u]] = a[u]%2 == a[v]%2 ? 1:0; //合并的关键 p[p[u]] = p[v]; } } } return 0; }
相关文章推荐
- [Commons]——双向Map
- 由二叉树的后序和中序结果求取先序结果
- 15 个实用的 PHP 正则表达式
- 作用域链,预解析,复杂面试题详解
- Nginx 使用IP限制访问来源
- a毛 jquery 学习记 2(下) 基础核心
- 古典经济学和新古典经济学(转载自百度知道)
- sys用户登录出现错误提示 ORA-28009:connection as SYS should be as SYSDBA OR SYSOPER
- 线程池与工厂模式、代理模式的结合使用
- 【GOF23设计模式】_单例模式
- Python3使用requests模块显示下载进度
- J2EE+Tomcat环境配置
- J2EE+Tomcat环境配置
- J2EE+Tomcat环境配置
- J2EE+Tomcat环境配置
- J2EE+Tomcat环境配置
- J2EE+Tomcat环境配置
- J2EE+Tomcat环境配置
- J2EE+Tomcat环境配置
- Maven项目管理