CF963B
题意:每次消除度数为偶数的叶子节点以及它所有的边,问这个树能否被消除完,能消除完需要输出消除的顺序
做法:处理dfs序,用栈记录,先消除dfs序大的,若先消除根节点,其叶子节点要是无法消除就wa了,所以贪心消除最靠近叶子的节点
注意:注意度数为0也是偶数
代码:
#include<cstdio>
#include<stack>
#define maxn 200005
using namespace std;
int n,fa[maxn],deg[maxn],vis[maxn],head[maxn],tot;
stack<int>sta;
int ans[maxn],num;//记录答案
struct edge{int to,next;}e[maxn<<1];
inline void add(int u,int v){e[++tot] = (edge){v,head[u]};head[u] = tot;}
inline int read(){
int x=0; char c=std::getchar();
while(c<'0'||c>'9')c=std::getchar();
while(c>='0'&&c<='9'){x=(x<<3)+(x<<1)+(c^48);c=std::getchar();}
return x;
}
void dfs1(int x,int f){//处理dfs序
fa[x] = f; sta.push(x);
for(int i = head[x];i;i = e[i].next){
int v = e[i].to;
if(v == f) continue;
dfs1(v,x);
}
}
void dfs2(int x){
vis[x] = 1; ans[++num] = x;
for(int i = head[x];i;i = e[i].next){
int v = e[i].to; deg[v] --;
if(v == fa[x] || vis[v]) continue;
if(!(deg[v] & 1)) dfs2(v);
}
}
int main(){
n = read(); int v;
for(int i = 1;i <= n;i++){
v = read();
if(v){
add(i,v); add(v,i);
++deg[v]; ++deg[i];
}
}
dfs1(1,-1);
while(!sta.empty()){
int az = sta.top();
sta.pop();
if(!(deg[az] & 1)) dfs2(az);
}
if(num == n){ puts("YES");
for(int i = 1;i <= num;i++)
printf("%d\n",ans[i]);
}
else puts("NO");
return ~~(0^0)*(0^0);
}