UVA11987:Almost Union-Find (并查集的删除)
2017-09-04 21:02
253 查看
题意:
三个指令分别为:1:合并p,q所在的两个集合;
2:将p移动到q的集合中。
3:查询p所在集合的元素个数和元素之和。
难点在于第二个指令,不能简单的合并,因为p有可能是根节点。
所以再开一个id数组,记录p的编号。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#define mx 100010
using namespace std;
int fa[mx],sum[mx],id[2*mx];
int cen[mx],n,m,de;
void init(){
for(int i = 1;i < mx;i ++){
id[i] = sum[i] = fa[i] = i;
cen[i] = 1;
}
de = n;
}
int find(int x){
return x == fa[x] ? x : fa[x] = find(fa[x]);
}
void uni(int x,int y){
x = find(x);
y = find(y);
if(x != y){
fa[x] = y;
sum[y] += sum[x];
cen[y] += cen[x];
}
}
void move(int x){
int fx = find(id[x]);
sum[fx] -= x;
cen[fx] -= 1;
id[x] = ++de;
cen[id[x]] = 1;
fa[id[x]] = id[x];
sum[id[x]] = x;
}
int main(){
while(scanf("%d%d",&n,&m)!=EOF){
int cm,a,b;
init();
for(int i = 0; i < m; i++){
scanf("%d",&cm);
if(cm == 1){
scanf("%d%d",&a,&b);
uni(id[a],id[b]);
}
else if(cm == 2){
scanf("%d%d",&a,&b);
if(find(id[a]) == find(id[b])) continue;
move(a);
uni(id[a],id[b]);
}
else {
scanf("%d",&a);
a=find(id[a]);
cout<<cen[a]<<" "<<sum[a]<<endl;
}
}
}
return 0;
}
三个指令分别为:1:合并p,q所在的两个集合;
2:将p移动到q的集合中。
3:查询p所在集合的元素个数和元素之和。
难点在于第二个指令,不能简单的合并,因为p有可能是根节点。
所以再开一个id数组,记录p的编号。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#define mx 100010
using namespace std;
int fa[mx],sum[mx],id[2*mx];
int cen[mx],n,m,de;
void init(){
for(int i = 1;i < mx;i ++){
id[i] = sum[i] = fa[i] = i;
cen[i] = 1;
}
de = n;
}
int find(int x){
return x == fa[x] ? x : fa[x] = find(fa[x]);
}
void uni(int x,int y){
x = find(x);
y = find(y);
if(x != y){
fa[x] = y;
sum[y] += sum[x];
cen[y] += cen[x];
}
}
void move(int x){
int fx = find(id[x]);
sum[fx] -= x;
cen[fx] -= 1;
id[x] = ++de;
cen[id[x]] = 1;
fa[id[x]] = id[x];
sum[id[x]] = x;
}
int main(){
while(scanf("%d%d",&n,&m)!=EOF){
int cm,a,b;
init();
for(int i = 0; i < m; i++){
scanf("%d",&cm);
if(cm == 1){
scanf("%d%d",&a,&b);
uni(id[a],id[b]);
}
else if(cm == 2){
scanf("%d%d",&a,&b);
if(find(id[a]) == find(id[b])) continue;
move(a);
uni(id[a],id[b]);
}
else {
scanf("%d",&a);
a=find(id[a]);
cout<<cen[a]<<" "<<sum[a]<<endl;
}
}
}
return 0;
}
相关文章推荐
- Uva11987 Almost Union-Find 并查集带删除
- UVA11987_Almost Union-Find(并查集删除操作)
- uva11987 - Almost Union-Find 并查集删除元素
- UVA 11987 Almost Union-Find(带删除的并查集)
- UVA 11987 Almost Union-Find(并查集的删除)
- uva 11987 Almost Union-Find(并查集的删除操作)
- UVA - 11987 Almost Union-Find(带删除的并查集)
- UVA 11987 Almost Union-Find(带有删除操作的并查集)
- 并查集(删除) UVA 11987 Almost Union-Find
- UVA 11987 Almost Union-Find 并查集的删除操作 懒惰标记
- UVA11987 - Almost Union-Find (并查集带删除)
- UVA 11987 Almost Union-Find(有删除操作的并查集)
- 11987 - Almost Union-Find(并查集删除操作)
- UVA 11987 Almost Union-Find (带权并查集的操作及并查集的删除操作)
- UVa-11987 Almost union-find(带删除操作的并查集)
- UVA 11987 Almost Union-Find 并查集节点删除
- uva11987 Almost Union-Find(可删除元素的并查集)
- UVa 11987 Almost Union-Find(支持删除操作的并查集)
- uva 11987 Almost Union-Find(带删除操作的并查集)
- UVA - 11987 Almost Union-Find[并查集 删除]