POJ 1947 Rebuilding Roads (树形DP)

来源:互联网 发布:批量修改照片尺寸软件 编辑:程序博客网 时间:2024/05/21 09:25

思路:设dp[i][j]为以i为根节点的子树中,形成j个节点(包含i)的子树需要切断的最少路数。

那么初值dp[i][0] = 1,dp[i][1] = 0;

dp[u][j] = min(dp[u][j-k]+dp[v][k],dp[u][j])。


代码:

#include<cstdio>#include<iostream>#include<cstring>using namespace std;const int maxn = 200;const int inf = 0x3f3f3f3f;struct Nod{int b,next;void init(int b,int next){this->b=b;this->next=next;}}buf[maxn<<1];int len,E[maxn];int n,m,num[maxn],dp[maxn][maxn];void init(){memset(E,-1,sizeof(E));len=0;int i,j;for(i=0;i<maxn;i++)for(j=0;j<maxn;j++)dp[i][j] = (j==0||j==1) ? 0 : inf;}void add_edge(int a,int b){buf[len].init(b,E[a]);E[a]=len++;buf[len].init(a,E[b]);E[b]=len++;}void dfs(int u,int pre){int i,j,k,v;num[u] = 1;for(i=E[u];i!=-1;i=buf[i].next){v=buf[i].b;if(v == pre) continue;dfs(v,u);num[u] += num[v];for(j=num[u];j>=1;j--){dp[u][j] = dp[u][j] + 1 ;for(k=1;k<j;k++)dp[u][j] = min(dp[u][j],dp[u][j-k]+dp[v][k]);        }}}int main(){init();int i,j,a,b;scanf("%d%d",&n,&m);for(i=1;i<n;i++){scanf("%d%d",&a,&b);add_edge(a,b);}dfs(1,-1);    int res = dp[1][m];    for(i=2;i<=n;i++) res = min(res,dp[i][m]+1);printf("%d\n",res);return 0;}


0 0