Tinkoff Internship Warmup Round 2018 and Codeforces Round #475 (Div. 2) D. Destruction of a Tree

题目链接:D. Destruction of a Tree

题意:给你一颗树每次你能删除偶数度的点,删除点后与之相连的边也会删除。问能否删除整棵树。能的话输出删除顺序。

题解:首先我们可以发现每次删除只能删出偶数条边,所以当给的树是偶数个点的树是无法删除的。

然后对于一颗有奇数个节点的树,我们先把每个节点以这个节点为根节点的树的大小求出了。然后先删除离根节点最远的为偶数的节点,那它的子树的大小一定是为奇数的,就可以继续递归处理。

#include<bits/stdc++.h>
#include<set>
#include<cstdio>
#include<iomanip>
#include<iostream>
#include<string>
#include<cstring>
#include<algorithm>
#define pb push_back
#define ll long long
#define PI 3.14159265
#define ls l,m,rt<<1
#define rs m+1,r,rt<<1|1
#define eps 1e-7
using namespace std;
typedef unsigned long long ull;
const int mod=1e9+9;
const ll inf=0x3f3f3f3f3f3f3f;
const int maxn=2e5+5;
int n,a,k,rt;
int siz[maxn];
bool vis[maxn];
vector<int>g[maxn];
vector<int>son[maxn];
void dfs1(int v)
{
    siz[v]=1;
    for(int i=0;i<g[v].size();i++)
    {
        dfs1(g[v][i]);
        siz[v]+=siz[g[v][i]];
        if(siz[g[v][i]]%2==0)
        {
            son[v].pb(g[v][i]);
        }
    }

}
void dfs(int v)
{
    vis[v]=true;
    for(int i=0;i<son[v].size();i++)
    {
        dfs(son[v][i]);
    }
    printf("%d\n",v);
    for(int i=0;i<g[v].size();i++)
    {
        if(!vis[g[v][i]])dfs(g[v][i]);
    }
}
int main()
{
   scanf("%d",&n);
   for(int i=1;i<=n;i++)
   {
       scanf("%d",&k);
       if(k==0)rt=i;
       g[k].pb(i);
   }
   if(n%2==0)
   {
       printf("NO\n");
   }
   else
   {
       printf("YES\n");
       dfs1(rt);
       dfs(rt);
   }
    return 0;
}

 

posted @ 2018-04-19 22:48  lhclqslove  阅读(124)  评论(0编辑  收藏  举报