POJ 1703 并查集的应用 关系并查集l两种方法
来源:互联网 发布:淘宝的免费模板在哪里 编辑:程序博客网 时间:2024/05/21 03:25
/*****************有两个帮派,有两种操作 D a b表示a 和 b不是一个帮派;A a b 表示询问a b是否是一个帮派,若至此还不确定,输出“Not sure yet”。思路:关系并查集;只要两者的关系确定了,就将他们放入同一个集合内,而另外增加一个表示关系的数组r[ ]来表示该节点与其父亲的关系。0表示同一类,1表示不同类。初始时集合只有自己一个元素,r[ ]设置为0。通过Find(int x) 来更新每个节点与新的父节点之间的关系通过Union() 来更新父节点 (即两个集合进行合并),来确定被更新的父节点作为子节点与 现在父节点之间的关系。******************/#include<iostream>#include<cstring>#include<cstdio>#include<algorithm>#include<cmath>#include<map>#define LL long long#define INF 0x3f3f3f3fusing namespace std;const int N=110000;int bin[N];int ran[N];void init(int n){ for(int i=0;i<=n;i++){ bin[i]=i; ran[i]=0 ; ///表示和根节点是同一个集合的 }}int Find(int x){ if(bin[x]!=x){ int fa=bin[x]; bin[x]=Find(bin[x]);///最最原始的根一定是ran[fa]==0; ran[x]=(ran[x]+ran[fa])%2; /// 由已知根的关系 推出后代的关系 } return bin[x];}void Union(int x,int y){ int fx=Find(x); int fy=Find(y); if(fx!=fy){ bin[fx]=fy; /// 已经知道x与y的关系是 不同集合关系 /// ran[x]记录的是与fx的关系, ran[y]记录的是与fy的关系 ///由这两个关系推出fx与 根fy的关系 ran[fx]=(ran[x]+ran[y]+1)%2; ///自己模拟一下 }}int main(){ int t,n,m,u,v; char s[10]; scanf("%d",&t); while(t--){ scanf("%d%d",&n,&m); init(n); for(int i=1;i<=m;i++){ scanf("%s%d%d",s,&u,&v); if(s[0]=='A'){ if(Find(u)==Find(v)){ ///对后代与根的关系进行了更新 if(ran[u]==ran[v]){ puts("In the same gang."); } else puts("In different gangs."); } else puts("Not sure yet."); } else Union(u,v); } } return 0;}
方法二
<pre name="code" class="cpp">/***********************************/#include<iostream>#include<cstring>#include<cstdio>#include<algorithm>#include<cmath>#include<map>#define LL long long#define INF 0x3f3f3f3fusing namespace std;const int N=110000;int bin[2*N];int ran[N];int Find(int x){ return bin[x]==x?x:bin[x]=Find(bin[x]);}void Union(int x,int y){ int fx=Find(x); int fy=Find(y); if(fx!=fy){ bin[fx]=fy; }}int main(){ int t,u,v,n,m; char s[10]; scanf("%d",&t); while(t--){ scanf("%d%d",&n,&m); for(int i=0;i<=2*n;i++){ bin[i]=i; } while(m--){ scanf("%s%d%d",s,&u,&v); if(s[0]=='D'){ Union(u,v+n); Union(u+n,v); } else{ if(Find(u)==Find(v)){ ///三个关系之间存在相反的相反关系,那就是相等 puts("In the same gang."); } else if(Find(u+n)==Find(v)){///||Find(u)==Find(v+n); puts("In different gangs."); } else puts("Not sure yet."); } } }}
1 0
- POJ 1703 并查集的应用 关系并查集l两种方法
- poj 1703(并查集的边权向量关系)
- POJ-1703并查集应用
- POJ 1182 1703 并查集的应用
- 并查集的两种实现
- 并查集的两种写法
- POJ 1182 食物链【关系并查集】
- 关系并查集 处理关系的方法
- POJ 1703 并查集
- poj-1703 并查集
- poj 1703 并查集
- POJ 1703 (并查集)
- poj 1703(并查集)
- POJ-1703 并查集
- POJ-1703 并查集
- POJ 1703 (并查集)
- poj 1703 并查集
- poj 1703 并查集
- BZOJ 1012 [JSOI2008]最大数maxnumber
- RxBus学习之旅--从入门到提高
- 1024. Palindromic Number (25)
- Codeforces Round #367 (Div. 2) D. Vasiliy's Multiset(字典树模板)
- Python类和对象
- POJ 1703 并查集的应用 关系并查集l两种方法
- Android的Service使用
- 分块算法讲解
- Oulipo poj3461 简单的KMP
- POJ 1416 - Shredding Compan
- 大牛经历
- 如何转载别人的博客
- priority_queue<int,vector<int>,greater<int>>优先队列 按照由小到大顺序
- C语言printf函数输出表达式中的计算顺序