D. Destruction of a Tree
题意:
一棵树,每次可选择一个度为偶数的点删掉,并且这个点连的边也删掉,问最后能否把所有点删掉。
tags:
注意到一个点:要把一棵树全部删掉,那它的点数一定是奇数。因为每次是删掉偶数条边,只有所有的边数是偶数时才能全部删掉。
所以在 dfs 的时候,如果一个子树的 Size 是偶数,那就要先删掉这棵子树才能删 root 点。
// 964D
#include<bits/stdc++.h>
using namespace std;
#pragma comment(linker, "/STACK:102400000,102400000")
#define rep(i,a,b) for (int i=a; i<=b; ++i)
#define per(i,b,a) for (int i=b; i>=a; --i)
#define mes(a,b) memset(a,b,sizeof(a))
#define INF 0x3f3f3f3f
#define MP make_pair
#define PB push_back
#define fi first
#define se second
typedef long long ll;
const int N = 200005;
int n, deg[N], sz[N];
vector< int > G[N];
void dfs_sz(int u, int fa) {
++sz[u];
for(int to : G[u]) if(to!=fa) {
dfs_sz(to, u);
sz[u] += sz[to];
}
}
vector< int > ans;
bool dfs(int u, int fa) {
for(int to : G[u])
if(to!=fa && !(sz[to]&1))
{
if(!dfs(to, u)) return false;
--deg[u];
}
if(deg[u]&1) return false;
ans.PB(u);
for(int to : G[u])
if(to!=fa && (sz[to]&1))
{
--deg[to];
if(!dfs(to, u)) return false;
}
return true;
}
int main()
{
scanf("%d", &n);
int pi;
rep(i,1,n) {
scanf("%d", &pi);
if(pi!=0) {
G[i].PB(pi), G[pi].PB(i);
++deg[i], ++deg[pi];
}
}
dfs_sz(1, -1);
if(dfs(1,-1)) {
puts("YES");
for(int v : ans) printf("%d
", v);
}
else puts("NO");
return 0;
}