http://codeforces.com/contest/964/problem/D
从叶子节点往上,如果度为偶数,删除并返回True,否则返回False,统计子节点连边的度数时就是统计False的度加父节点的。
#include<bits/stdc++.h>
using namespace std;
#define maxn 300005
vector<int> tree[maxn];
vector<int> v_destroy;
int vis[maxn];
bool vis_destroy[maxn];
void dfs_destroy(int root,int fa) {
if(!vis_destroy[root]) {
vis_destroy[root]=1;
v_destroy.push_back(root);
}
for(int i=0;i<tree[root].size();i++)
{
if(tree[root][i]==fa) continue;
if(!vis_destroy[tree[root][i]])
dfs_destroy(tree[root][i],root);
}
}
bool dfs(int root,int fa) {
// cout<<root<<endl;
vis[root]=1;
int sum=1;
for(int i=0;i<tree[root].size();i++)
{
if(!vis[tree[root][i]]&&!dfs(tree[root][i],root)) sum++;
}
if(root==1) {
sum--;
}
if(sum%2==0) {
dfs_destroy(root,fa);
return true;
}
return false;
}
int main()
{
memset(vis,0,sizeof(vis));
memset(vis_destroy,0,sizeof(vis_destroy));
int n,k;
int p;
cin>>n;
for(int i=1;i<=n;i++)
{
scanf("%d",&p);
if(!p) continue;
tree[i].push_back(p);
tree[p].push_back(i);
}
if(dfs(1,0)) {
cout<<"YES"<<endl;
for(int i=0;i<v_destroy.size();i++)
cout<<v_destroy[i]<<endl;
}
else {
cout<<"NO"<<endl;
}
}