zoukankan      html  css  js  c++  java
  • CF963B Destruction of a Tree(思维+贪心)

    题目告诉我们偶数度数才能删除,我们观察hint,发现他们的叶子结点是放在最后删除的

    这点启发了我们,为什么要把叶子结点放在最后删呢,因为他的度数一定是1,也就是必须父亲删了他才能删。

    所以,当儿子的个数为偶数,一定是父节点删了才能删他。从这方面考虑过去,当儿子节点为奇数呢?

    我们发现,除了根节点外,其他节点可以在这个时候删除,因为他还有一条连在父亲的边。

    但是他也可以选择不删啊,等其他点删了再说,为了避免无谓的讨论,我们需要一种固定的删法

    所以我们可以想到从叶子往上求,能删就删,之后再从根往下,看看能否把所有都删除。注意特判根

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    typedef pair<int,int> pll;
    const int N=4e5+10;
    const int inf=1e9;
    int h[N],e[N],ne[N],idx;
    int st[N];
    int vis[N],f[N];
    vector<int> ans;
    int sign;
    void add(int a,int b){
        e[idx]=b,ne[idx]=h[a],h[a]=idx++;
    }
    void dfs(int u,int fa){
        int i;
        int cnt=0;
        for(i=h[u];i!=-1;i=ne[i]){
            int j=e[i];
            if(j==fa)
                continue;
            f[j]=u;
            dfs(j,u);
            if(vis[j]){
                continue;
            }
            else{
                cnt++;
            }
        }
        if(cnt%2&&u!=1){
            vis[u]=1;
            ans.push_back(u);
        }
        if(u==1){
            sign=cnt;
        }
    }
    void dfs1(int u,int fa){
        int i;
        for(i=h[u];i!=-1;i=ne[i]){
            int j=e[i];
            if(j==fa)
                continue;
            if(vis[f[j]]&&!vis[j]){
                ans.push_back(j);
                vis[j]=1;
            }
            dfs1(j,u);
        }
    }
    int main(){
        ios::sync_with_stdio(false);
        memset(h,-1,sizeof h);
        int i;
        int n;
        cin>>n;
        for(i=1;i<=n;i++){
            int x;
            cin>>x;
            if(x!=0){
                add(x,i);
                add(i,x);
            }
        }
        dfs(1,0);
        if(!vis[1]&&sign%2==0){
            ans.push_back(1);
            vis[1]=1;
        }
        dfs1(1,0);
        if((int)ans.size()<n){
            cout<<"NO"<<endl;
        }
        else{
            cout<<"YES"<<endl;
            for(auto x:ans){
                cout<<x<<endl;
            }
        }
        return 0;
    }
    View Code
    没有人不辛苦,只有人不喊疼
  • 相关阅读:
    java--volatile关键字
    java--线程异常处理器
    java--线程池
    Supervisor安装和使用
    网络协议--HTTP
    1.Nginx简介
    Nginx配置实战
    Redis面试题
    SpringBoot--集成swagger2
    缓存的优缺点
  • 原文地址:https://www.cnblogs.com/ctyakwf/p/13739497.html
Copyright © 2011-2022 走看看