Codeforces 963B Destruction of a Tree 思维+dfs
题目大意:
给出一棵树,每次只能摧毁有偶数个度的节点,摧毁该节点后所有该节点连着的边都摧毁,判断一棵树能否被摧毁,若能,按顺序输出摧毁的点,如果有多种顺序,输出一种即可
基本思路:
1)我一开始自然而然想到的,当然是贪心,首先判断能否可行,然后我是想先从叶子到根摧毁一编,然后从根开始再摧毁,我觉得应该可行,还没试验;
2)rank前10的代码,我就不不自量力的去评价了,自己体会吧。
代码如下:
#include<cstdio> #include<cmath> #include<cstring> #include<iostream> #include<string> #include<algorithm> #include<queue> #include<vector> using namespace std; typedef long long ll; typedef long long LL; typedef pair<int,int> pii; const int inf = 0x3f3f3f3f; const int maxn = 200000+10; const ll mod = 1e9+9; vector<int>gra[maxn]; bool ispos[maxn]; bool dfs(int u,int pre){ bool ans=1; int sz=gra[u].size(); for(int i=0;i<sz;i++){ int v=gra[u][i]; if(v==pre) continue; ispos[v]=dfs(v,u); if(ispos[v]) ans^=1; } return ans; } void print(int u,int pre){ int sz=gra[u].size(); for(int i=0;i<sz;i++){ int v=gra[u][i]; if(v==pre) continue; if(!ispos[v]) print(v,u); } printf("%d\n",u); for(int i=0;i<sz;i++){ int v=gra[u][i]; if(v==pre) continue; if(ispos[v]) print(v,u); } } int main(){ int n,rt; scanf("%d",&n); for(int i=1;i<=n;i++){ int u; scanf("%d",&u); if(!u){ rt=i; }else{ gra[u].push_back(i); gra[i].push_back(u); } } bool flag=dfs(rt,0); if(flag){ printf("YES\n"); print(rt,0); }else{ printf("NO\n"); } return 0; }