• codeforces 964D


    Destruction of a Tree

    题意:给一个n个节点的树, 每次可以删除度为偶数的节点,并把与之相连的边删除,问是否可以把所有节点删除

    思路:有一个结论,偶数节点的树一定不可以全部删除, 证明:首先,删除一个点一定删除偶数条边,一个偶数节点的树肯定不能一次把所有边删除,因为偶数点的树有奇数条边,那么删除一个点以后同时删除偶数条边的结果是:得到了偶数颗树,并且这些树的节点数之和为奇数,也就是说必然有一颗树的大小还是偶数,也就是说明,一颗大小为偶数的树无论怎么删都会留下大小为偶数的子树,由前面推得的结论可知,偶数节点的树一定不可以全部删除。那么只需要dfs判断每个节点可不可以删除即可,一个节点是否可以删除取决于它的子树的大小是否全为奇数,同时如果一个节点删除了,那么必然影响到它孩子的度树,所以在删除完一个节点以后要堆它的孩子继续dfs

    AC代码:

    #include "iostream"
    #include "iomanip"
    #include "string.h"
    #include "stack"
    #include "queue"
    #include "string"
    #include "vector"
    #include "set"
    #include "map"
    #include "algorithm"
    #include "stdio.h"
    #include "math.h"
    #pragma comment(linker, "/STACK:102400000,102400000")
    #define bug(x) cout<<x<<" "<<"UUUUU"<<endl;
    #define mem(a,x) memset(a,x,sizeof(a))
    #define step(x) fixed<< setprecision(x)<<
    #define mp(x,y) make_pair(x,y)
    #define pb(x) push_back(x)
    #define ll long long
    #define endl ("
    ")
    #define ft first
    #define sd second
    #define lrt (rt<<1)
    #define rrt (rt<<1|1)
    using namespace std;
    const ll mod=1e9+9;
    const ll INF = 1e18+1LL;
    const int inf = 1e9+1e8;
    const double PI=acos(-1.0);
    const int N=2e5+100;
    
    int n, fu, p[N], du[N], vis[N*2], as[N], siz[N];
    int head[N*2], to[N*2], nex[N*2], tot=1;
    
    void add(int u, int v) {
        to[tot] = v;
        nex[tot] = head[u];
        head[u] = tot++;
    }
    vector<int> ans;
    
    void dfs0(int u, int fa) {
        siz[u] = 1;
        for(int i=head[u]; i!=-1; i=nex[i]) {
            int v = to[i];
            if(v == fa) continue;
            dfs0(v, u);
            siz[u] += siz[v];
        }
    }
    
    void dfs(int u,  int fa) {
        if(ans.size() >= n || as[u]) return;
        if(du[u]%2 == 0) {
            int sz=0;
            for(int i=head[u]; i!=-1; i=nex[i]) {
                int v = to[i];
                if(as[v]) continue;
                if(v == p[u]) sz = n-siz[u];
                else sz = siz[v];
                if(sz%2 == 0) return;
            }
            as[u] = 1, ans.pb(u);
            for(int i=head[u]; i!=-1; i=nex[i]) {
                int v = to[i];
                if(v == fa) continue;
                du[v]--;
                dfs(v, u);
            }
        }
    }
    
    int main() {
        scanf("%d", &n);
        mem(head, -1);
        for(int i=1; i<=n; ++i) {
            scanf("%d", &p[i]);
            if(p[i] != 0) {
                add(i, p[i]), add(p[i], i);
                du[i]++, du[p[i]]++;
            }
            else fu = i;
        }
        dfs0(fu, 0);
        for(int i=1; i<=n; ++i) {
            if(du[i]%2==0) dfs(i, 0);
            if(ans.size() >= n) break;
        }
        for(int i=1; i<=n ; ++i) {
            if(!as[i]) return 0*printf("NO");
        }
        printf("YES
    ");
        for(auto i : ans) printf("%d
    ", i);
        return 0;
    }
  • 相关阅读:
    jquery总结01-基本概念和选择器
    git学习笔记总结
    git学习笔记12-标签管理-版本
    vue 图片下载到本地,图片保存到本地
    Failed to mount component: template or render function not defined.
    javascript 错误监控
    javascript 跨域 的几种方法
    解决跨域脚本攻击 XSS
    标准时间转YYYY-MMM-DD
    javascript时间戳和日期字符串相互转换
  • 原文地址:https://www.cnblogs.com/max88888888/p/8877951.html
Copyright © 2020-2023  润新知