• 1358. 分割树


    1358. 分割树

    现在有一棵树T,有N个节点,我们想通过去掉一个节点p来把T分割成更小的树,并且满足每个小树中的节点数不超过n/2。

    请根据输入的树来输出所有可能的p的号码。

    树形dp

    在遍历树的过程中,访问每个node,维护两个值:

    1. 所有子树的结点数的最大值childmax
    2. 所有子树(这里包括node)的结点数之和sum。

    递归过程中用上一层的sum,不断更新这一层的childmax。

    而childmax和sum则共同用来判断这个node是否可以删除。

    下面再分析判断条件: childmax<=n/2 && n-sum<=n/2

    childmax<=n/2 :去掉node后,原先node的子树均满足条件。

    n-sum<=n/2  :去掉node后,原先除node和node的所有子树外的树(就当是node的祖先树吧)均满足条件。

    #include <cstdio>
    #include <iostream>
    #include <cstring>
    #include <algorithm>
    #include <vector>
    using namespace std;
    typedef long long LL;
    #define mst(s, t) memset(s, t, sizeof(s))
    const int INF = 0x3f3f3f3f;
    const int maxn = 10010;
    vector<int> G[maxn];
    int ans[maxn], num, n;
    int dfs(int node, int father){
        int sum = 1, childmax = 0;   //若是叶子结点则return sum=1,否则求其子树(包括自己)的总结点数
        for(int i=0; i<G[node].size(); i++){
            if(G[node][i] == father)continue; //因为是树结构,这里可以在无向时避免遍历成环
            int sum_son = dfs(G[node][i], node);
            childmax = max(sum_son, childmax);//所有子树的结点数的最大值
            sum += sum_son;//sum:node的子树的结点数和
        }
        childmax = max(childmax, n-sum);
        if(childmax <= n/2){
            /*
             * 当node结点的孩子结点的结点数最大为Sum,若Sum<=n/2,则该点符合条件
             * 因为去掉node后,任意子树结点数<=n/2, max()保证其非子树结点和仍<=n/2
             * 故该点满足条件
            */
            ans[num++] = node;
        }
        return sum;
    }
    int main()
    {
        //freopen("in.txt", "r", stdin);
        scanf("%d", &n);
        for(int i=0; i<n-1; i++){
            int a, b;
            scanf("%d%d", &a, &b);
            G[a].push_back(b);
            G[b].push_back(a);
        }
        num = 0;
        int tmp = dfs(1, 0);
        //cout << n << "==" << tmp << endl; //验证
        sort(ans, ans+num);
        if(num){
            for(int i=0; i<num; i++){
                printf("%d
    ", ans[i]);
            }
        }else{
            printf("NONE
    ");
        }
        return 0;
    }
  • 相关阅读:
    计算机网络 chapter 6 应用层
    计算机网络 chapter 4 网络层
    计算机网络 chapter 2 物理层
    计算机网络 chapter3数据链路层
    计算机网络 chapter 1 概述
    文章
    进程池线程池 协程
    MySQL
    同步锁 死锁与递归锁 信号量 线程queue event事件
    GIL全局解释器
  • 原文地址:https://www.cnblogs.com/liulex/p/11394298.html
Copyright © 2020-2023  润新知