zoukankan      html  css  js  c++  java
  • luogu_P1272 重建道路

    很好的一道树上DP

    我会告诉你我想那个“-2”想了一个下午吗?


    题面:
    一场可怕的地震后,人们用N个牲口棚(1≤N≤150,编号1..N)重建了农夫John的牧场。由于人们没有时间建设多余的道路,所以现在从一个牲口棚到另一个牲口棚的道路是惟一的。因此,牧场运输系统可以被构建成一棵树。John想要知道另一次地震会造成多严重的破坏。有些道路一旦被毁坏,就会使一棵含有P(1≤P≤N)个牲口棚的子树和剩余的牲口棚分离,John想知道这些道路的最小数目。

    输入:
    第1行:2个整数,N和P
    第2..N行:每行2个整数I和J,表示节点I是节点J的父节点。

    输出:
    单独一行,包含一旦被破坏将分离出恰含P个节点的子树的道路的最小数目。


    分析:

    (dp[i][j])表示计算至(i)时,分离出整颗大小为(j)的子树(包括(i))所需切掉的最少道路数。

    初始化一个点的时候,把它的所有连边给去掉,(dp[i][1]=du[i])

    父节点每与一个子节点合并,需要将dp之和-2,为什么?

    因为在初始化时,已经将u的(u->v)去掉,也已经将(v)(v->u)去掉,而如果想将含(u)连通块与含(v)连通块相连,这条边不能被去掉。

    然后我一直在想为什么每一次都要减去2

    答案是:我们的dp操作规则是默认一开始所有的点都被切开,所以我们的运算要遵循这个规则,每一次计算也就是一次合并,无论哪两个dp值都遵循着不与外界联系的规律,所以两个dp值相加一定要-2.


    code:

    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    using namespace std;
    const int INF=0x3f3f3f3f;
    const int N=201;
    struct Edge{
        int to,next;
    }e[N*2];
    int du[N],a[N],dp[N][N];
    int n,k,res=INF,EdgeCnt=0;
    void addedge(int u,int v){
        int p=++EdgeCnt;
        e[p].to=v;e[p].next=a[u];
        a[u]=p;
    }
    void dfs(int u,int fa){
        dp[u][1]=du[u];
        for (int p=a[u];p;p=e[p].next){
            int v=e[p].to;
            if (v!=fa){
                dfs(v,u);
                for (int j=k;j>=1;j--)
                    for (int k=1;k<=j;k++)
                        dp[u][j]=min(dp[u][j],dp[u][j-k]+dp[v][k]-2);
            }
        }
        res=min(res,dp[u][k]);
    }
    int main(){
        scanf("%d%d",&n,&k);
        memset(dp,0x3f,sizeof(dp));
        for (int i=1;i<n;i++){
            int u,v;
            scanf("%d%d",&u,&v);
            addedge(u,v);
            addedge(v,u);
            du[u]++;du[v]++;
        }
        dfs(1,0);
        printf("%d",res);
        return 0;
    }
    
  • 相关阅读:
    PHP compact() 函数
    JS动态插入HTML后不能执行后续JQUERY操作
    find命令
    服务提供者框架模式
    Ant的使用
    git的常用命令
    结合程序崩溃后的core文件分析bug
    设备特殊文件
    函数chdir、fchdir和getcwd
    静态库和动态库
  • 原文地址:https://www.cnblogs.com/GUOGaby/p/14031612.html
Copyright © 2011-2022 走看看