题意:
一棵树,每次可选择一个度为偶数的点删掉,并且这个点连的边也删掉,问最后能否把所有点删掉。 tags: 注意到一个点:要把一棵树全部删掉,那它的点数一定是奇数。因为每次是删掉偶数条边,只有所有的边数是偶数时才能全部删掉。 所以在 dfs 的时候,如果一个子树的 Size 是偶数,那就要先删掉这棵子树才能删 root 点。// 964D#includeusing 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 secondtypedef 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\n", v); } else puts("NO"); return 0;}