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;
}

  

posted @ 2018-04-19 13:06  愿~得偿所愿,不负时光  阅读(191)  评论(0编辑  收藏  举报