• 台州 OJ 1553 Rebuilding Roads 树状DP


    题意:给一棵树,要求去掉最少的边得到一颗孤立的正好 P 个结点的树

    第一次接触树状DP,瞎搞好久,看别人的代码看懂的,涨姿势了。

    代码:

    #include <iostream>
    #include <cstring>
    #include <vector>
    using namespace std;
    
    const int MAX = 155;
    const int inf = 0x3fffffff; 
    
    int n, p;
    vector<int> G[MAX];        //
    int tot[MAX];
    int dp[MAX][MAX];        //子树 i 为 j 个结点时要去掉的最少的边数 
    int ans;
    
    int getTot(int root);    //求出每一棵子树一共有多少个结点
    void dfs(int root);        //求解 dp 数组 
    
    int main(){
        //freopen("input.txt", "r", stdin);
        ans = inf;
        memset(tot, 0, sizeof(tot));
        for(int i=0; i<MAX; i++)
            G[i].clear();
        
        cin >> n >> p; 
        for(int i=1; i<n; i++){
            int father, child;
            cin >> father >> child;
            G[father].push_back(child);
        }
        getTot(1);
        dfs(1);
        cout << ans;
    }
    
    int getTot(int root){
        int sum = 1;    //包括根 
        for(int i=0; i<G[root].size(); i++){
            sum += getTot(G[root][i]);
        }
        tot[root] = sum;
        return sum;
    }
    
    void dfs(int root){
        dp[root][1] = G[root].size();    //只有一个结点时,删掉所有孩子的边
        dp[root][tot[root]] = 0;
        for(int i=2; i<=p; i++){
            dp[root][i] = inf;
        }
        
        for(int i=0; i<G[root].size(); i++){
            int child = G[root][i];
            dfs(child);
            for(int j=tot[root]; j>=1; j--){        //取 j 个结点 (如果是从小到大,会对后面的有影响,dp[root][j-k] 可能包含在子树里面取了的情况,这时再在子树里取就出错了) 
                for(int k=1; k<=tot[child] && k<j; k++){    //子树取 k 个结点 
                    dp[root][j] = min(dp[root][j], dp[root][j-k] + dp[child][k] - 1);
    //                cout << root << " " << j << " " << k << " " << dp[root][j] << " " << child << endl;
                }
            }
        }
        
        ans = min(ans, dp[root][p] + (root!=1));
    }
  • 相关阅读:
    后端MVC与前端MVVM的区别
    解析身份证号
    awk的执行方式
    案例九:shell脚本自动创建多个新用户,并设置密码
    一键配置tomcat定期日志清理功能
    date命令
    将dict.define转化成dict.txt
    FastDFS 配置 Nginx 模块及访问测试
    nohup命令的用法
    手把手教你如何玩转消息中间件(ActiveMQ)
  • 原文地址:https://www.cnblogs.com/lighter-blog/p/7229516.html
Copyright © 2020-2023  润新知