CF717E

题目大意

给定一颗n个节点的树,n<=10^5
每个节点有一个颜色, 黑色或白色。
你需要输出一条从节点1开始行走的,长度不超过10^7的路径,规定每走到一个节点就会改变其颜色(注意初始站在1不会改变1的颜色),每次只能走向相邻的节点,你输出的路径需要使所有结点都变成黑色。

构造一波

我们用solve(x)表示从x开始走,最后回到x,任务是将以x为根的子树中除了x以外的节点都变成黑色(x的颜色可以任意)。
具体呢,先往每个子树走,走回来后,如果x一个儿子y是白色,就从x走到y再走回x把y变黑。最后退出。
这样做一遍后,除了1以外都是黑色,然后如果1是白色,找到一个1的儿子(一定是黑色),走过去走回来再走过去然后结束路径。
这样就全黑了。然后路径长度也不会很大。

#include<cstdio> 
#include<algorithm>
#define fo(i,a,b) for(i=a;i<=b;i++)
using namespace std;
const int maxn=200000+10;
int h[maxn],go[maxn*2],next[maxn*2],a[maxn];
int ans[10000000+10],sta[100];
int i,j,k,l,t,n,m,top,tot,cnt;
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'){
        x=x*10+ch-'0';
        ch=getchar();
    }
    return x*f;
}
void add(int x,int y){
    go[++tot]=y;
    next[tot]=h[x];
    h[x]=tot;
}
void solve(int x,int y){
    int t=h[x];
    while (t){
        if (go[t]!=y){
            ans[++top]=go[t];
            a[go[t]]=-a[go[t]];
            solve(go[t],x);
            ans[++top]=x;
            a[x]=-a[x];
            if (a[go[t]]==-1){
                ans[++top]=go[t];
                a[go[t]]=1;
                ans[++top]=x;
                a[x]=-a[x];
            }
        }
        t=next[t];
    }
}
void write(int x){
    if (!x){
        putchar('0');
        putchar(' ');
        return;
    }
    cnt=0;
    while (x){
        sta[++cnt]=x%10;
        x/=10;
    }
    while (cnt) putchar(sta[cnt--]+'0');
    putchar(' ');
}
int main(){
    n=read();
    fo(i,1,n) a[i]=read();
    fo(i,1,n-1){
        j=read();k=read();
        add(j,k);add(k,j);
    }
    ans[top=1]=1;
    //dfs(1,0);
    solve(1,0);
    if (a[1]==-1){
        t=go[h[1]];
        ans[++top]=t;
        ans[++top]=1;
        ans[++top]=t;
    }
    fo(i,1,top) write(ans[i]);
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值