• poj1947Rebuilding Roads(树形DP)


    链接

    刚接触 树上背包。。有点抽象化 找好父亲和儿子的关系 及状态转移方程 

    代码里有详细的注释  就不解释了

     1 #include <iostream>
     2 #include<cstdio>
     3 #include<cstring>
     4 #include<algorithm>
     5 #include<stdlib.h>
     6 using namespace std;
     7 #define N 155
     8 #define INF 0xfffffff
     9 int n,m;
    10 int w[N][N],o[N],dp[N][N];
    11 void add(int u,int v)
    12 {
    13     w[u][o[u]++] = v;//不在乎内存的邻接表
    14 }
    15 void dfs(int root)
    16 {
    17     int i,j;
    18     for(i = 0; i <= m ; i++)
    19     dp[root][i] = INF;//类似背包的初始化 
    20     dp[root][1] = 0;//如果保留一个节点 就不需要切 那个加1 会在后面有
    21     for(i = 0; i < o[root] ; i++)
    22     {
    23         int son = w[root][i];
    24         dfs(son);//搜到叶子 树都这样
    25         for(j = m ; j>=0 ; j--)
    26         {
    27             int minz = INF,k;
    28             for(k = 0 ; k < j ; k++)
    29             minz = min(minz,dp[root][k]+dp[son][j-k]);//这个是对于本儿子来言 找一个能够让父亲保留J个节点的最好办法
    30             dp[root][j] = min(dp[root][j]+1,minz);//是保留之前j个节点的取法(就是不要本儿子 切掉) 还是要本儿子的方法
    31         }
    32     }
    33 }
    34 int main()
    35 {
    36     int i;
    37     while(scanf("%d",&n)!=EOF)
    38     {
    39         memset(o,0,sizeof(o));
    40         scanf("%d",&m);
    41         for(i = 1; i < n ;i++)
    42         {
    43             int u,v;
    44             scanf("%d%d",&u,&v);
    45             add(u,v);
    46         }
    47         dfs(1);
    48         int ans = dp[1][m];//树根的话就不用加切祖先那一刀了
    49         for(i = 2; i <= n ; i++)
    50         ans = min(ans,dp[i][m]+1);//剩下的都要+1
    51         cout<<ans<<endl;
    52     }
    53     return 0;
    54 }
    View Code
  • 相关阅读:
    es6箭头函数
    微信小程序入门
    浏览器常见错误代码
    nginx学习
    windows下mongodb安装与使用整理
    mongodb简单的增删改查
    github入门到上传本地项目
    Robomongo
    对象(面向对象、创建对象方式、Json)
    代码编辑器——Visual Studio Code
  • 原文地址:https://www.cnblogs.com/shangyu/p/3279480.html
Copyright © 2020-2023  润新知