题意:给你一颗树每次你能删除偶数度的点,删除点后与之相连的边也会删除。问能否删除整棵树。能的话输出删除顺序。
题解:首先我们可以发现每次删除只能删出偶数条边,所以当给的树是偶数个点的树是无法删除的。
然后对于一颗有奇数个节点的树,我们先把每个节点以这个节点为根节点的树的大小求出了。然后先删除离根节点最远的为偶数的节点,那它的子树的大小一定是为奇数的,就可以继续递归处理。
#include<bits/stdc++.h> #include<set> #include<cstdio> #include<iomanip> #include<iostream> #include<string> #include<cstring> #include<algorithm> #define pb push_back #define ll long long #define PI 3.14159265 #define ls l,m,rt<<1 #define rs m+1,r,rt<<1|1 #define eps 1e-7 using namespace std; typedef unsigned long long ull; const int mod=1e9+9; const ll inf=0x3f3f3f3f3f3f3f; const int maxn=2e5+5; int n,a,k,rt; int siz[maxn]; bool vis[maxn]; vector<int>g[maxn]; vector<int>son[maxn]; void dfs1(int v) { siz[v]=1; for(int i=0;i<g[v].size();i++) { dfs1(g[v][i]); siz[v]+=siz[g[v][i]]; if(siz[g[v][i]]%2==0) { son[v].pb(g[v][i]); } } } void dfs(int v) { vis[v]=true; for(int i=0;i<son[v].size();i++) { dfs(son[v][i]); } printf("%d ",v); for(int i=0;i<g[v].size();i++) { if(!vis[g[v][i]])dfs(g[v][i]); } } int main() { scanf("%d",&n); for(int i=1;i<=n;i++) { scanf("%d",&k); if(k==0)rt=i; g[k].pb(i); } if(n%2==0) { printf("NO "); } else { printf("YES "); dfs1(rt); dfs(rt); } return 0; }