【AGC014E】Blue and Red Tree 并查集 启发式合并
2017-10-25 16:37
483 查看
题目描述
有一棵n个点的树,最开始所有边都是蓝边。每次你可以选择一条全是蓝边的路径,删掉其中一条,再把这两个端点之间连一条红边。再给你一棵树,这棵树的所有边都是红边,问你最终能不能把原来的树变成这棵新树。n≤100000
题解
考虑最后一条加的边,那么当前也有一条相同的蓝边。也就是说,如果把这两棵树合在一起,这两个点之间会有两条边。然后可以把这两个点缩成一个点。所以我们每次选择之间有两条边的一对点,把这两个点合在一起。可以直接遍历度数较小的那个点x相邻的边,把这条边的另一个端点v向度数较大的那个点y连边。顺便用并查集维护每个点缩点之后是什么点。
时间复杂度:O(nlog2n)
代码
#include<cstdio> #include<cstring> #include<algorithm> #include<cstdlib> #include<ctime> #include<utility> #include<map> #include<queue> #include<set> using namespace std; typedef long long ll; typedef unsigned long long ull; typedef pair<int,int> pii; int n; map<ll,int> a; queue<pii> q; set<int> l[100010]; int f[100010]; int find(int x) { return f[x]==x?x:f[x]=find(f[x]); } ll getid(int x,int y) { if(x>y) swap(x,y); return ll(x)*n+y; } void link(int x,int y) { l[x].insert(y); l[y].insert(x); ll v=getid(x,y); a[v]++; if(a[v]==3) { printf("NO\n"); exit(0); } if(a[v]==2) q.push(pii(x,y)); } int main() { #ifdef DEBUG freopen("b.in","r",stdin); freopen("b.out","w",stdout); #endif scanf("%d",&n); int i,x,y; for(i=1;i<=2*n-2;i++) { scanf("%d%d",&x,&y); link(x,y); } for(i=1;i<=n;i++) f[i]=i; for(i=1;i<n;i++) { while(1) { if(q.empty()) { printf("NO\n"); return 0; } x=q.front().first; y=q.front().second; q.pop(); if(x!=y) break; } if(l[x].size()>l[y].size()) swap(x,y); f[x]=y; a.erase(getid(x,y)); l[y].erase(x); for(auto v:l[x]) { v=find(v); if(v==y) continue; a.erase(getid(x,v)); link(v,y); l[v].erase(x); l[x].erase(v); } } printf("YES\n"); return 0; }
相关文章推荐
- Red/Blue Spanning Tree----HDU_4263----并查集and生成树
- [AtCoder AGC014 .E][杂题]Blue and Red Tree
- Codeforces 741D D. Arpa’s letter-marked tree and Mehrdad’s Dokhtar-kosh paths 树上启发式合并
- 并查集-- HDU - 4263 Red/Blue Spanning Tree
- [树上启发式合并 && 哈希] Codeforces 741D. Arpa’s letter-marked tree and Mehrdad’s Dokhtar-kosh paths
- AtCoder Grand Contest 014 E - Blue and Red Tree 乱搞
- 【AGC014】E - Blue and Red Tree
- AtCoder AGC14E-Blue and Red Tree 并查集+启发式合并+STL
- [agc14e]Blue and Red Tree
- CodeForces 827D Best Edge Weight (倍增 启发式合并 链剖 并查集)
- [PKU 3715]Blue and Red(最小点覆盖集)
- 并查集的启发式合并 和 路径压缩
- 并查集——启发式合并,路径压缩
- poj 3715 Blue and Red(二分图最大匹配+字典序输出)
- 【CodeForces 339B】Red and Blue Balls 找规律
- HDU 4263 Red/Blue Spanning Tree【最小生成树原理】
- COCI 2017/2018 Round #3,November 25th,2017 Pictionary [带权并查集+启发式合并]
- Hdu 3726 Graph and Queries(并查集+平衡树+启发式合并)
- 树上启发式合并 DSU On Tree
- BNUOJ 26229 Red/Blue Spanning Tree