zoukankan      html  css  js  c++  java
  • 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
    ");
    }
  • 相关阅读:
    Python for Data Science
    Python for Data Science
    Python for Data Science
    Python for Data Science
    Python for Data Science
    Python for Data Science
    Python for Data Science
    Python for Data Science
    Python for Data Science
    软件工程实践总结
  • 原文地址:https://www.cnblogs.com/8023spz/p/8893785.html
Copyright © 2011-2022 走看看