codeforces 963B Destruction of a Tree

You are given a tree (a graph with n vertices and n - 1 edges in which it's possible to reach any vertex from any other vertex using only its edges).

A vertex can be destroyed if this vertex has even degree. If you destroy a vertex, all edges connected to it are also deleted.

Destroy all vertices in the given tree or determine that it is impossible.


Input

The first line contains integer n (1 ≤ n ≤ 2·105) — number of vertices in a tree.

The second line contains n integers p1, p2, ..., pn (0 ≤ pi ≤ n). If pi ≠ 0 there is an edge between vertices i and pi. It is guaranteed that the given graph is a tree.

Output

If it's possible to destroy all vertices, print "YES" (without quotes), otherwise print "NO" (without quotes).

If it's possible to destroy all vertices, in the next n lines print the indices of the vertices in order you destroy them. If there are multiple correct answers, print any.

Examples
Input
5
0 1 2 1 2
Output
YES
1
2
3
5
4
Input
4
0 1 2 3
Output
NO
Note

In the first example at first you have to remove the vertex with index 1 (after that, the edges (1, 2) and (1, 4) are removed), then the vertex with index 2 (and edges (2, 3) and (2, 5) are removed). After that there are no edges in the tree, so you can remove remaining vertices in any order.

#include <iostream>
#include <queue>
#include <cmath>
#include <string>
#include <cstring>
#include <vector>
#include <cstdio>
///临近叶子结点的偶数度数结点容易被改变成奇数度数,假如他的双亲结点是偶数,消除了双亲节点,他就变成度数为1,而它还连着一片叶子也就是孤立的两个点都是奇数都无法删除
///所以从树的叶子往根进行遍历,进行检查。
using namespace std;
int u[400010],v[400010],fir[400010],nex[400010],vis[200010],val[200010],ans[200010],ant,f[200010],n,d,root;
void check(int t)
{
    int k = fir[t];
    while(k != -1)
    {
        val[v[k]] --;
        if(!vis[v[k]] && v[k] != f[t] && val[v[k]] % 2 == 0)
        {
            vis[v[k]] = 1;
            ans[ant ++] = v[k];
            check(v[k]);
        }
        k = nex[k];
    }
}
void dfs(int t)///遍历整棵树
{
    int k = fir[t];
    while(k != -1)
    {
        if(v[k] != f[t])
        {
            dfs(v[k]);
        }
        k = nex[k];
    }
    if(val[t] % 2 == 0)///在这之前 左右子树一定都遍历过
    {
        vis[t] = 1;
        ans[ant ++] = t;
        check(t);
    }
}
int main()
{
    int c = 0;
    scanf("%d",&n);
    memset(fir,-1,sizeof(fir));
    for(int i = 1;i <= n;i ++)
    {
        scanf("%d",&d);
        f[i] = d;
        if(d)
        {
            val[i] ++;
            val[d] ++;
            u[c] = i;
            v[c] = d;
            u[c + n - 1] = d;
            v[c + n - 1] = i;
            nex[c] = fir[u[c]];
            fir[u[c]] = c;
            nex[c + n - 1] = fir[u[c + n - 1]];
            fir[u[c + n - 1]] = c + n - 1;
            c ++;
        }
        else root = i;
    }
    dfs(root);
    if(ant == n)
    {
        printf("YES
");
        for(int i = 0;i < ant;i ++)
        {
            printf("%d
",ans[i]);
        }
    }
    else printf("NO
");
}
原文地址:https://www.cnblogs.com/8023spz/p/8893785.html