AT2675 Two Trees

传送门

AT2675 Two Trees


题目描述

给你两棵树,让你求出满足令两棵树所有子树和的绝对值为1,让你构造一组情况,如果不能则输出IMPOSSIBLE。

算法分析

先观察每个点的奇偶性,如果这两棵树对应值连奇偶性都不同,那肯定是不可能的。如果可能的话,跑一遍欧拉回路,如果这个点是偶点则肯定是0,如果是奇点的话,如果该点是指向第二棵树的,则为-1,否则是1。
个人感觉欧拉回路更像是一种配对的过程,是-1,1更均匀的分散看。


注:欧拉回路是一定要优化一下否则肯定会gg


#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int N=110000;
int a[N],b[N],root1,root2,p[N*2],h[N*2],num,n,ans[N*2],f[N*2];
bool flag[N],flag1;
struct node{
    int x,y,next,k;
    bool flag;
}data[N*10];
void link(int x,int y){
    ++num;
    data[num].x=x;
    data[num].y=y;
    data[num].next=h[x];
    data[num].k=num+1;
    data[num].flag=true;
    h[x]=num;
    ++num;
    data[num].x=y;
    data[num].y=x;
    data[num].next=h[y];
    data[num].k=num-1;
    data[num].flag=true;
    h[y]=num;
    p[x]++;
    p[y]++;
}
void dfs1(int x){
    for(int &i=h[x];i!=-1&&i!=0;i=data[i].next){
    	int v=data[i].y;
        if(!data[i].flag)continue;
        if(x<=n&&v<=n){f[x]++;f[v]--;}
        if(flag1&&x==root1&&v==root2){f[x]++;f[v]--;flag1=false;}
        if(flag1&&x==root2&&v==root1){f[x]++;f[v]--;flag1=false;}
        data[i].flag=false;
        data[data[i].k].flag=false;
        dfs1(v);
    }
}
int main(){
    scanf("%d",&n);
    memset(h,-1,sizeof h);
    for(int i=1;i<=n;i++){
        scanf("%d",&a[i]);
        if(a[i]!=-1)link(a[i],i);
        else root1=i;
    }
    for(int i=1;i<=n;i++){
        scanf("%d",&b[i]);
        if(b[i]!=-1)link(b[i]+n,i+n);
        else root2=i+n;
    }
    link(root1,root2);flag1=true;
    for(int i=1;i<=n;i++){
        if((p[i]%2)!=(p[i+n]%2)){
            printf("IMPOSSIBLE\n");
            return 0;
        }else if(p[i]%2==1)link(i,i+n);
    }
    printf("POSSIBLE\n");
    dfs1(root1);
    for(int i=1;i<=n;i++)printf("%d ",f[i]);
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值