poj 1703 poj1182(并查集)
来源:互联网 发布:mac seesheer试色 编辑:程序博客网 时间:2024/06/05 06:43
poj1703: 题目大意:有n个人分别属于两个团伙,两种操作 D a b表示a b不在同一团伙,A a b表示询问a b是否在同一团伙首先要对并查集的基本概念了解,fa[]代表每个元素的父亲是谁,rank[]数组代表的是树的深度,但是根据不同题意会有不同的意义,这个对理解题意很重要。
那么对与这道题,刚开始每个节点都是一棵树,各自的父亲是自己,后来合并,即每个犯罪人都是一个节点,两个人的关系就是一条线,从而逐渐形成一棵树。
这棵树的边相连的两个点是代表不是一个团伙。其实我理解的是深度相同的都属于同一门派,但是这里只有两个门派,所以根据敌人的敌人是朋友的原则,这里rank[]数组的处理就好理解了,所以深度只有0,1.(这种处理方式在下一题会有更好的解释)。
////可以把每个人看做一个点 每个关系看做一条边,rank[]本来表示树的深度,在这里表示点之间的权值,两点之间每条线权值为1,// rank[]依然是深度,表示该点到根节点的深度,如果两个点在同一个集合,并且深度一样,那么就是同一个帮派。#include<iostream>#include<cstdio>#include<cstring>#include<cmath>using namespace std;#define maxn 100005int n;int fa[maxn];int rank[maxn];void Init() //初始化{for(int i=0;i<=n;i++){fa[i]=i;rank[i]=0;}}int find(int x){if(fa[x]!=x){int father=find(fa[x]);rank[x]=(rank[x]+rank[fa[x]])%2;fa[x]=father;return fa[x];} return x;}void Union(int x,int y)//合并两个集合 相当于加一条边{int a=find(x);int b=find(y); //find 的时候依次更新rank[]fa[a]=b;rank[a]=(rank[x]+rank[y]+1)%2;}int main(){int cas;scanf("%d",&cas);while(cas--){int m,a,b,i;char ch[3];scanf("%d%d",&n,&m); Init();for(i=1;i<=m;i++){scanf("%s%d%d",ch,&a,&b);if(ch[0]=='D'){Union(a,b);}else{if(n==2)printf("In different gangs.\n");else if(find(a)==find(b)){if(rank[a]==rank[b])printf("In the same gang.\n");elseprintf("In different gangs.\n");}elseprintf("Not sure yet.\n");}}}return 0;}poj1182
题目大意:
食物链 关系有三种情况 rank[] 表示与父亲的关系 0 同类 1 吃父亲,2 被父亲吃
关于向量的问题,这里有牛人很好的说明。O(∩_∩)O哈哈~ 我也是站在巨巨的肩膀上\(^o^)/~
http://www.cnblogs.com/wuyiqi/archive/2011/08/24/come__in.html
另外这个题还WA了好多次,其一是要单组数据才能过,其二就是合并的时候父节点写反辣。。噗噗。。
//食物链 关系有三种情况 rank[] 表示与父亲的关系 0 同类 1 吃父亲,2 被父亲吃// 应该是和上一道提一样的 但总觉得有些不明白的地方//好多牛人啊。。向量 tx ty 分别为x y 与其的父亲的关系,已知 x->tx x->y y->ty// 求 tx->ty 因为两个合并时要fa[ty]=tx;// tx->ty = tx->x+x->y+y->ty// so:tx->ty=(-rank[x]+d-1+rank[y])%3;=(rank[y]-rank[x]+d-1)%3#include<iostream>#include<cstdio>#include<cstring>#include<cmath>using namespace std;int n;int fa[55555];int rank[55555];void Init(){ for(int i=1;i<=n;i++) { fa[i]=i; rank[i]=0; }}int find(int x){ if(fa[x]!=x) { int fath=find(fa[x]); rank[x]=(rank[x]+rank[fa[x]])%3; return fa[x]=fath; // 路径压缩 的时候rank[]如何修改呢? // fa[x]=ffa[x] x->tx tx->ttx so:x->ttx=(rank[x]+rank[fa[x]])%3; } return x;} int Union(int d,int x,int y){if(x>n || y>n)return 1; if(d==1 && x==y)return 1; int tx=find(x); int ty=find(y); if(tx==ty) { if((rank[y]-rank[x]+3)%3!=d){return 1; } else return 0; } else { fa[ty]=tx; //这里不能写反了。。。 rank[ty]=(rank[x]-rank[y]+d+3)%3; return 0; }}int main(){//freopen("q.in","r",stdin); int k,d,x,y,res,i; scanf("%d%d",&n,&k)==2; res=0; Init(); for( i=1;i<=k;i++) { scanf("%d%d%d",&d,&x,&y); if(Union(d-1,x,y))res++; } cout<<res<<endl; }
0 0
- poj 1703 poj1182(并查集)
- 并查集 poj1182
- POJ1182-并查集
- poj1182----并查集
- 并查集--poj1182
- 并查集&poj1182
- poj1182(并查集)
- 食物链 POJ1182 -- 并查集
- poj1182 食物链 (并查集)
- poj1182 并查集 食物链
- poj1182食物链 并查集
- poj1182 种类并查集
- poj1182+hdu1892(并查集)
- poj1182 并查集
- poj1182 种类并查集
- 并查集-POJ1182食物链
- POJ1182 - 食物链 - 并查集
- 并查集 食物链 POJ1182
- java代理模式的学习(动态代理+静态代理)
- LeetCode——Unique Binary Search Trees II
- c# 删除对话框
- UVa452 - Project Scheduling(AOE问题)
- sgu103
- poj 1703 poj1182(并查集)
- 【2014.0804】
- 完全匹配-最大匹配
- URAL 1933 Guns for Battle!
- Total Commander 搜索指定类型并且包含特定内容的文件
- 文本处理
- 64位系统下注册32位dll文件
- ACM中的C++
- poj2456Aggressive cows(二分+贪心)