Codeforces Round #475 (Div. 2) D. Destruction of a Tree
题意:给你一棵树, 只能删度数为偶数的点, 问你能不能将整个图删完, 如果能输入删除的顺序。
思路:对于一棵树来说, 如果里面的点的个数是偶数个则肯定不可能, 偶数个点有奇数条边,而你每次删只能删偶数条边。
那么我们对于每个父亲儿子来说, 如果儿子的子树的大小为奇数, 那么肯定先删父亲, 反之先删儿子, 建立关系图, 跑一遍拓扑序就好啦。
1 #include<bits/stdc++.h> 2 #define LL long long 3 #define fi first 4 #define se second 5 #define mk make_pair 6 #define pii pair<int,int> 7 #define ull unsigned long long 8 using namespace std; 9 10 const int N=1e6+7; 11 const int M=100+7; 12 const int inf=0x3f3f3f3f; 13 const LL INF=0x3f3f3f3f3f3f3f3f; 14 const int mod=1e9 + 9; 15 16 vector<int> edge[N], e[N], ans; 17 int n, cnt[N], deg[N]; 18 int vis[N]; 19 void dfs(int u ,int pre) { 20 cnt[u] = 1; 21 for(int v : edge[u]) { 22 if(v == pre) continue; 23 dfs(v, u); 24 cnt[u] += cnt[v]; 25 } 26 } 27 28 bool dfs2(int u) { 29 vis[u] = -1; 30 for(int v : e[u]) { 31 if(vis[v] == -1) 32 return false; 33 if(!vis[v] && !dfs2(v)) 34 return false; 35 } 36 vis[u] = 1; 37 ans.push_back(u); 38 return true; 39 } 40 41 void dfs3(int u, int pre) { 42 for(int v : edge[u]) { 43 if(v == pre) continue; 44 if(cnt[v] % 2) { 45 e[u].push_back(v); 46 deg[v]++; 47 } else { 48 e[v].push_back(u); 49 deg[u]++; 50 } 51 dfs3(v, u); 52 } 53 } 54 55 int main() { 56 scanf("%d", &n); 57 for(int i = 1; i <= n; i++) { 58 int fa; scanf("%d", &fa); 59 if(fa) { 60 edge[fa].push_back(i); 61 edge[i].push_back(fa); 62 } 63 } 64 if(n % 2 == 0) { 65 puts("NO"); 66 return 0; 67 } 68 69 dfs(1, 0); 70 dfs3(1, 0); 71 72 for(int i = 1; i <= n; i++) { 73 if(vis[i]) continue; 74 if(!dfs2(i)) { 75 puts("NO"); 76 return 0; 77 } 78 } 79 puts("YES"); 80 for(int i = ans.size() - 1; i >= 0; i--) 81 printf("%d\n", ans[i]); 82 return 0; 83 } 84 /* 85 */