标签:esc amp math XML 生成 之间 input 测试 thml
sample input 1:
3
1 2
2 3
1 3
3 2
sample input 2:
5
1 2
2 3
3 4
4 5
3 4
2 4
1 4
1 5
sample input 3:
6
1 2
3 5
4 6
1 6
5 1
5 3
1 4
2 6
4 3
5 6
sample output 1:
YES
sample output 2:
YES
sample output 3:
NO
样例 1 :
目标可以达成:* 2≤N≤105
* 1≤ai,bi,ci,di≤N
* ai≠bi
* ci≠di
* 输入的两个图都是树。
如果可以做到将红树变为蓝树,那么在改变完N-2条边后,最后的没有连上一条蓝边必与最后一条红边重合
那么这一条重合的边可以在以前所有的连边中任意使用
那么我们可以对于原树中每一条既是红的又是蓝的边的两个端点缩成一个点(删去原本连接他们的边,再把其中一个点的所有边转到另一个点上,用启发式合并来缩点)
如果最终整棵树能够缩成一个点,那么就是YES,否则就是NO
启发式合并的总耗时是O(nlogn)
所以整个算法的时间复杂度是O(nlogn)
#include<iostream> #include<cstdio> #include<set> using namespace std; struct data{ int x,y; }t[200001]; int n,m,f[200001],x,y,cnt; set<int> v[200001]; int fa(int a){ if(f[a]!=a)f[a]=fa(f[a]); return f[a]; } void ins(int a,int b){ set<int>::iterator id1=v[a].find(b),id2=v[b].find(a); if(id1==v[a].end()){ v[a].insert(b); v[b].insert(a); }else{ cnt++; v[a].erase(b); v[b].erase(a); t[cnt].x=a; t[cnt].y=b; } } int main(){ scanf("%d",&n); for(int i=1;i<=n*2-2;i++){ scanf("%d%d",&x,&y); ins(x,y); } for(int i=1;i<=n;i++)f[i]=i; while(cnt){ x=fa(t[cnt].x); y=fa(t[cnt].y); cnt--; if(v[x].size()>v[y].size())swap(x,y); f[x]=y; for(int i:v[x]){ v[i].erase(x); ins(i,y); } v[x].clear(); m++; } if(m==n-1)printf("YES\n"); else printf("NO\n"); }
noip2019集训测试赛(二十一)Problem B: 红蓝树
标签:esc amp math XML 生成 之间 input 测试 thml
原文地址:https://www.cnblogs.com/ez-syh/p/11548844.html