uva 11987 删点并查集
2015-08-19 12:07
288 查看
题意:三种操作 1. 合并两个集合 2.把x放到y所在的集合 3.输出x所在集合的元素个数和元素的和
思路:删点并查集 相当与给每个元素套了一个壳。
思路:删点并查集 相当与给每个元素套了一个壳。
#include <bits/stdc++.h> using namespace std; int fa[200010]; long long sum[200010]; int num[200010]; int idx[200010]; int getf(int a) { if(fa[a] != a) fa[a] = getf(fa[a]); return fa[a]; } void merge(int a, int b) { int x = getf(a); int y = getf(b); if(x != y) { fa[y] = x; sum[x] += sum[y]; num[x] += num[y]; } } int cnt; void Delete(int x) { int f = getf(idx[x]); num[f] --; sum[f] -= x; idx[x] = ++cnt; num[idx[x]] = 1; sum[idx[x]] = x; fa[idx[x]] = cnt; } void init(int n) { for(int i=1; i<=n; i++) fa[i] = sum[i] = idx[i] = i,num[i]=1; } int n,m; int main() { while(cin>>n>>m) { init(n); cnt = n; int cmd,x,y; while(m--) { scanf("%d", &cmd); if(cmd == 1) { scanf("%d %d", &x, &y); merge(idx[x], idx[y]); } else if(cmd == 2) { scanf("%d %d", &x, &y); if(getf(idx[x]) != getf(idx[y])) { Delete(x); merge(idx[y], idx[x]); } } else { scanf("%d", &x); int tt = getf(idx[x]); printf("%d %lld\n", num[tt],sum[tt]); } } } return 0; }
相关文章推荐
- HDU-1213-How Many Tables
- Longest Consecutive Sequence,Distinct Subsequences,Interleaving String,Scramble String
- SARS病毒传染 并查集
- HDU 1213
- CSU1307 并查集+SPFA
- BestWiring——Kruskal算法&并查集
- HDU-1233 还是畅通工程(最小生成树&并查集)
- Simon-【深入理解数据结构】有根树的不同实现① —— 并查集
- 家族
- poj 1417 True Liars 解题报告 并查集 DP
- poj 1161
- 并查集——HDOJ 1213How Many Tables解题报告
- 最小生成树——HDOJ 2988 Dark roads解题报告
- HDU 1198 Farm Irrigation(并查集)
- hdu 1213 How Many Tables(并查集,简单题)
- hud 1233 还是畅通工程( kruskal和prim两种方法)
- hdu 1863 畅通工程 (最小生成树kruskal 算法)
- hdu 1213并查集
- hdu 1272并查集
- hdu 1198并查集