[agc018f]Two Trees
来源:互联网 发布:深圳压寨网络是培训么 编辑:程序博客网 时间:2024/06/05 16:10
前言
好题
题目大意
两颗树。
给每个节点赋一个权值,使得两颗树的任意子树点权和的绝对值为1。
构造
我们先来判断无解。
绝对值为1意味着模2等于1。
可以根据这点确定每个点在两棵树中的点权奇偶性。
存在矛盾即无解。
如果不存在矛盾,我们可以开始构造。
首先i在第一棵树的编号就是i,在第二棵树是i+n。
原树的边先不动,我们增加一个节点s向两个根节点连边。
对于一个i,如果其点权为奇数,我们就连i和i+n一条边。
然后容易发现新的图任意点度数为偶数,存在欧拉回路。
我们做一个欧拉回路,然后对于一个i,如果其点权为偶数就赋值为0。
如果为奇数,在欧拉回路中是从i走到i+n那么赋值为1否则赋值为-1。
可以证明这样构造是正确的(考虑对于任意点只要在欧拉回路中走向一个不为父亲的节点子树和就+1,从一个不为父亲的节点走过来子树和就-1,那么任意节点子树和都是1或-1,欧拉回路保证了任意点进等于出)
#include<cstdio>#include<algorithm>#define fo(i,a,b) for(i=a;i<=b;i++)using namespace std;const int maxn=100000+10;int ans[maxn],d[maxn*2],fa[maxn*2],h[maxn*2],now[maxn*2],go[maxn*6],nxt[maxn*6],sta[maxn*6];bool bz[maxn*6],czy;int i,j,k,l,r,s,t,n,m,tot,top,rot1,rot2;/*int read(){ int x=0,f=1; char ch=getchar(); while (ch<'0'||ch>'9'){ if (ch=='-') f=-1; ch=getchar(); } while (ch>='0'&&ch<='9'){ }}*/void add(int x,int y){ go[++tot]=y; nxt[tot]=h[x]; h[x]=tot;}void dfs(int x,int y){ int t=h[x]; while (t){ if (go[t]!=y){ dfs(go[t],x); d[x]^=1; } t=nxt[t]; } d[x]^=1;}void travel(int x){ int t=now[x]; while (t=now[x]){ now[x]=nxt[t]; if (!bz[(t+1)/2]){ bz[(t+1)/2]=1; //now[x]=nxt[t]; travel(go[t]); } } sta[++top]=x;}int main(){ scanf("%d",&n); fo(i,1,n){ scanf("%d",&fa[i]); if (fa[i]==-1){ fa[i]=0; rot1=i; } else{ add(fa[i],i); add(i,fa[i]); } } fo(i,n+1,2*n){ scanf("%d",&fa[i]); if (fa[i]==-1){ fa[i]=0; rot2=i; } else{ add(fa[i]+n,i); add(i,fa[i]+n); } } dfs(rot1,0); dfs(rot2,0); czy=1; fo(i,1,n) if (d[i]^d[i+n]){ czy=0; break; } if (!czy){ printf("IMPOSSIBLE\n"); return 0; } printf("POSSIBLE\n"); s=0; add(s,rot1); add(rot1,s); add(s,rot2); add(rot2,s); fo(i,1,n) if (d[i]){ add(i,i+n); add(i+n,i); } fo(i,s,2*n) now[i]=h[i]; travel(s); fo(i,1,n) if (d[i]) ans[i]=-1; fo(i,1,top-1) if (sta[i]>0&&sta[i]<=n&&sta[i+1]==sta[i]+n) ans[sta[i]]=1; fo(i,1,n) printf("%d ",ans[i]);}
阅读全文
0 0
- [agc018f]Two Trees
- 【AGC018F】Two Trees 构造 黑白染色
- uva-two trees
- The Other Two Trees
- hdu5200 Trees( two points)
- The Other Two Trees
- Merge Two Binary Trees
- Merge Two Binary Trees
- Merge Two Binary Trees
- LeetCode Merge Two Trees
- Merge Two Binary Trees
- Merge Two Binary Trees
- Merge Two Binary Trees
- Merge Two Binary Trees
- Merge Two Binary Trees
- Merge Two Binary Trees
- 10250 - The Other Two Trees
- 10250 - The Other Two Trees
- [Kafka]Monitor Kafka with jmxtrans
- C++中的虚函数表
- HYSBZ2565-最长双回文串
- 装系统步骤
- Makefile框架
- [agc018f]Two Trees
- java8 Optional防止空指针异常初探
- 卡辛斯基的警告
- 《笨方法学python》习题43的学习笔记
- cx_oracle: UnicodeDecodeError:invalid continuation byte
- c语言顺序程序设计
- JAVA并发编程之——定时线程池
- 分布式与集群的区别
- OKhttp3的基本使用