传送门
题解:
欧拉回路构造题从来不写欧拉回路
正解好像是一个欧拉回路。
但是我并不想写欧拉回路。
于是xjb搞了一个二分图染色做法。
为了方便接下来所称呼的偶点,奇点都是指儿子数量+1的奇偶性。
首先所有叶子都是奇点。
所有偶点都有奇数个儿子,考虑令偶点本身的权值为0,它的某两个儿子配对,要求一个为+1,另一个为-1。那么剩下一个儿子就是贡献到它本身的值。
这样剩下这个儿子权值没有确定,显然这个儿子子树内部也有这样一个决定权值的点存在,我们把这个点上传,在祖先的地方为其寻找匹配点。
奇点只需要把自己考虑进去就行了。
两个树都搞一遍,用带权并查集维护颜色。
显然这样匹配出来是一个二分图,因为一个点只会有两条边,一条是在树A中进行匹配产生的边,另一条是在树B中匹配产生的边,这样交错下去,显然只有经过偶数条边才会回到自己。
代码:
#include<bits/stdc++.h>
#define ll long long
#define re register
#define gc get_char
#define cs const
namespace IO{
inline char get_char(){
static cs int Rlen=1<<22|1;
static char buf[Rlen],*p1,*p2;
return (p1==p2)&&(p2=(p1=buf)+fread(buf,1,Rlen,stdin),p1==p2)?EOF:*p1++;
}
template<typename T>
inline T get(){
char c;T num;bool f=false;
while(!isdigit(c=gc()))f=c=='-';num=c^48;
while(isdigit(c=gc()))num=(num+(num<<2)<<1)+(c^48);
return f?-num:num;
}
inline int gi(){return get<int>();}
}
using namespace IO;
using std::cerr;
using std::cout;
cs int N=1e5+7;
int n;
int col[N],fa[N],rk[N];
inline int gf(int u){
if(u==fa[u])return u;
int tp=gf(fa[u]);
col[u]^=col[fa[u]];
return fa[u]=tp;
}
inline void mg(int u,int v){
int fu=gf(u),fv=gf(v);
if(fu==fv)return ;
if(rk[fu]<rk[fv])std::swap(fu,fv);
else if(rk[fu]==rk[fv])++rk[fu];
col[fv]=col[u]^col[v]^1;
fa[fv]=fu;
}
struct Tree{
int last[N],nxt[N],to[N],ecnt;
int son[N],rt;
inline void adde(int u,int v){
++son[u];
nxt[++ecnt]=last[u],last[u]=ecnt,to[ecnt]=v;
}
inline void init(int n){
for(int re i=1;i<=n;++i){
int fa=gi();
if(fa==-1)rt=i;
else adde(fa,i);
}
}
int dfs(int u){
std::vector<int> nd;
if(!(son[u]&1))nd.push_back(u);
for(int re e=last[u],v=to[e];e;v=to[e=nxt[e]])nd.push_back(dfs(v));
for(int re i=1;i<nd.size();i+=2)mg(nd[i],nd[i+1]);
return nd[0];
}
}t1,t2;
signed main(){
#ifdef zxyoi
freopen("two_trees.in","r",stdin);
#endif
n=gi();t1.init(n);t2.init(n);
for(int re i=1;i<=n;++i)if((t1.son[i]^t2.son[i])&1)puts("IMPOSSIBLE"),exit(0);
for(int re i=1;i<=n;++i)fa[i]=i;
t1.dfs(t1.rt);t2.dfs(t2.rt);
puts("POSSIBLE");
for(int re i=1;i<=n;++i)
if(!(t1.son[i]&1))printf("%s ",(gf(i),col[i]?"1":"-1"));
else printf("0 ");
return 0;
}