题目大意:给你一棵树,每次只能删除度为2的结点,问你能否将整棵树删除,如果可以的话,就输出路径
题目分析,对于一棵树的某一个结点的子树来说,如果他的所有结点的度都是奇数,而该结点的度是偶数的话,那么其一定为一个能够先删除的结点,因为如果不先删除该结点,而先删除该结点的父结点,那么这个结点的度就会变为奇数,就不能被删除了
所以只要用dfs进行递归,找到需要的结点,再用dfs找路径即可
#include <bits/stdc++.h>
#define cl(a) memset(a,0,sizeof(a))
using namespace std;
const int maxn=2e5+50;
const int mod=1e9+7;
const int inf=0x3f3f3f3f;
typedef long long ll;
vector<int>E[maxn];
int n;
void addedge(int u,int v)
{
E[u].push_back(v);
E[v].push_back(u);
}
int degree[maxn];
int vis[maxn];
int del[maxn];
vector<int>ans;
void path(int u,int f)
{
for(int i=0;i<E[u].size();i++)
{
int v=E[u][i];
if(!del[v]&°ree[v]%2==0&&v!=f)
{
ans.push_back(v);
del[v]=1;
for(int j=0;j<E[v].size();j++)
{
int t=E[v][j];
degree[t]--;
}
path(v,u);
}
}
}
void dfs(int t,int f)
{
vis[t]=1;
//if(E[t].size()==0)return;
for(int i=0;i<E[t].size();i++)
{
int k=E[t][i];
if(!vis[k])
dfs(E[t][i],t);
}
if(degree[t]%2==0)
{
del[t]=1;
//cout<<t<<endl;
ans.push_back(t);
for(int i=0;i<E[t].size();i++)
{
int m=E[t][i];
if(!del[m])
{
degree[m]--;
}
}
path(t,f);
}
}
int main()
{
scanf("%d",&n);
cl(degree);
cl(vis);
cl(del);
for(int i=1;i<=n;i++)
{
int x;
scanf("%d",&x);
if(x!=0)
addedge(i,x);
}
for(int i=1;i<=n;i++)
{
degree[i]=E[i].size();
}
dfs(1,0);
int flag=1;
if(ans.size()==n)
{
puts("YES");
for(int i=0;i<ans.size();i++)
{
printf("%d\n",ans[i]);
}
}
else
{
puts("NO");
}
return 0;
}