• POJ 1655 Balancing Act (树形DP求树的重心)


    题意:

    求一棵树中以某个点为重心最小的子树集, 就是去掉这个点, 图中节点最多的联通块节点最少。

    分析:

    想知道这个点是不是最优的点, 只要比较它子树的数量和除去这部分其他的数量(它的父节点那部分树), 最后循环一遍找最优即可。

    #include<stdio.h>
    #include<vector>
    #include<algorithm>
    #include<string.h>
    #include<iostream>
    using namespace std;
    
    const int maxn = 25000 + 7;
    const int inf = 1e9 + 7;
    int Max[maxn];//记录以该节点为重心,子树节点的最大值
    int Num[maxn];//记录包括该节点不回溯到父亲节点有多少个子节点
    vector<int> G[maxn];
    int N;
    void init() {
        for(int i = 0; i < maxn; i ++) {
            G[i].clear();
        }
    }
    void dpMax(int u, int pre) {
    
        Num[u] = 1, Max[u] = 0;
    
        for(int i = 0; i < G[u].size(); i++) {
            int v = G[u][i];
            if(v == pre)
                continue;
            dpMax(v, u);
            Max[u] = max(Max[u], Num[v]);
            Num[u] += Num[v];
        }
        Max[u] = max(Max[u], N - Num[u]);//比较一下自己子树和父亲子树的最大值
    
    }
    int main() {
        int T;
        cin >> T;
        while(T--) {
            init();
            cin >> N;
            for(int i = 0; i < N - 1; i++) {
                int u, v;
                cin >> u >> v;
                G[u].push_back(v);
                G[v].push_back(u);
            }
    //        Max[0] = inf;
            dpMax(1, -1);
            int ansNum = inf, ansInd = 1;
            for(int i = 1; i <= N; i++){
                if(ansNum > Max[i]){
                    ansNum = Max[i];
                    ansInd = i;
                }
            }
            cout << ansInd << " " << ansNum << "
    ";
        }
        return 0;
    }
  • 相关阅读:
    next_permutation( ) 和prev_permutation( ) 全排列函数
    F
    STL入门
    H
    C
    提交按钮组件
    JScorllPane面板(带滚轮的JPane)
    JPanel画板
    网络布局管理器
    边界布局管理器
  • 原文地址:https://www.cnblogs.com/Jadon97/p/9155615.html
Copyright © 2020-2023  润新知