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
    ");
    }
  • 相关阅读:
    ERP类系统设计学习
    人工智能关键词
    系统性能
    连接不同服务器不同数据库
    socket一个例子
    SQLite
    asp.net 页面缓存、数据缓存
    原生js
    Android 网络调试 adb tcpip 开启方法
    C语言中string char int类型转换
  • 原文地址:https://www.cnblogs.com/8023spz/p/8893785.html
Copyright © 2011-2022 走看看