zoukankan      html  css  js  c++  java
  • 重建道路 树形DP

    重建道路 树形DP

    给一棵树,问最少断多少边使得这棵树树最终只有(p​)个节点

    设计dp状态(f[u][i][j])表示节点(u),到第(i)个儿子,使(j)个节点分离,但是不分离(u)最少需要断的边数。类比背包,容易得到转移方程:

    [f[u][i][j]=min{f[u][i-1][j-k]+f[v][n][k]} ]

    再优化一维(i),状态变为(f[u][j]),此时必须倒序遍历(j)

    需要注意的是,最后答案并不是(f[1][sz[1]-p]),因为最后可能把节点1也删了,所以必须在每个满足子树节点数(ge p)的节点处统计一下答案。

    [ans=min(f[u][sz[u]-p]+f[u][sz[u]], ans) ]

    其中注意(f[1][sz[1]]=0),因为不需要将树根与其父亲分离(它没父亲)

    #include <cstdio>
    #include <cstring>
    #define MAXN 155
    #define MIN(A,B) ((A)<(B)?(A):(B))
    using namespace std;
    int n,p,ans;
    int head[MAXN],nxt[MAXN*2],vv[MAXN*2],tot;
    inline void add_edge(int u, int v){
        vv[++tot]=v;
        nxt[tot]=head[u];
        head[u]=tot;
    }
    int f[MAXN][MAXN],sz[MAXN];
    void load(int u, int fa){
        sz[u]=1;
        f[u][0]=0;
        for(int i=head[u];i;i=nxt[i]){
            int v=vv[i];
            if(v==fa) continue;
            load(v, u);
            sz[u]+=sz[v];
        }
        f[u][sz[u]]=1;
    }
    void dfs(int u, int fa){
        for(int i=head[u];i;i=nxt[i]){
            int v=vv[i];
            if(v==fa) continue;
            dfs(v, u);
            for(int j=sz[u];j>=0;--j)
                for(int k=0;k<=MIN(sz[v], j);++k){
                    f[u][j]=MIN(f[v][k]+f[u][j-k], f[u][j]);
                }
        }
        if(sz[u]>=p) ans=MIN(f[u][sz[u]-p]+f[u][sz[u]], ans);
    }
    int main(){
        scanf("%d %d", &n, &p);
        for(int i=2;i<=n;++i){
            int u,v;
            scanf("%d %d", &u, &v);
            add_edge(u, v);
            add_edge(v, u);
        }
        memset(f, 0x3f, sizeof(f));
        ans=0x3f3f3f3f;
        load(1, 0);
        f[1][sz[1]]=0;
        dfs(1, 0);
        printf("%d", ans);
        return 0;
    }
    /*
    f[u][i][j]=min{f[u][i-1][j-k]+f[v][n][k]}
    */
    
    
  • 相关阅读:
    LeetCode1051. 高度检查器 Java
    LeetCode 面试题 16.04. 井字游戏 Java
    WPF 显示3D密集场景,堆场管理系统
    WPF 饼状图,柱形图,折线图 (3 饼状图)
    WPF 饼状图,柱形图,折线图 (2 折线图)
    WPF 饼状图,柱形图,折线图 (1 柱形图)
    wpf 实现控件拖拽(仿windows 桌面图标拖拽)
    设计模式-控制反转
    Socket 网络编程和IO模型
    wpf 滚动文字 跑马灯
  • 原文地址:https://www.cnblogs.com/santiego/p/11510964.html
Copyright © 2011-2022 走看看