1. 程式人生 > >codeforces 963B Destruction of a Tree

codeforces 963B Destruction of a Tree

das example this cst size destroy -h http tro

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\n");
        for(int i = 0;i < ant;i ++)
        {
            printf("%d\n",ans[i]);
        }
    }
    else printf("NO\n");
}

codeforces 963B Destruction of a Tree