codeforces 963B Destruction of a Tree
Posted 给杰瑞一块奶酪~
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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.
OutputIf 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.
Examples5
0 1 2 1 2
YES
1
2
3
5
4
4
0 1 2 3
NO
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的主要内容,如果未能解决你的问题,请参考以下文章