依赖背包变形——poj1947(经典)

前端之家收集整理的这篇文章主要介绍了依赖背包变形——poj1947(经典)前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
/* 还是树形的背包,dp[u][j]表示u的子树里,切割出一个大小为j的包含u的联通块的代价 那么dp[u][j]按照常规的依赖背包转移即可 初始状态时dp[u][1],切割掉u的所有儿子的代价 注意本题需要特别讨论u是根和非根的情况,即非根的儿子是度数-1,但是最后以这个点作为中心时就要加上这个减掉的1 */@H_502_16@
#include<bits/stdc++.h>@H_502_16@
#include<vector>
using namespace@H_502_16@ std;
#define N 205@H_502_16@
vector<int>@H_502_16@G[N];
int dp[N][N],n,p;//dp[u][j]表示u子树下取大小为j的联通块的代价 
void dfs(int u,int@H_502_16@ pre){
    for(int i=0;i<G[u].size();i++@H_502_16@){
        int v=@H_502_16@G[u][i];
        if(v==pre)continue@H_502_16@;
        dfs(v,u);
        for(int j=p;j>=1;j--@H_502_16@)
            for(int k=1;k<j;k++@H_502_16@)
                dp[u][j]=min(dp[u][j],dp[v][k]+dp[u][j-k]-1@H_502_16@);
    }
}
int@H_502_16@ main(){
    cin>>n>>@H_502_16@p;
    for(int i=1;i<n;i++@H_502_16@){
        int u,v;cin>>u>>@H_502_16@v;
        G[u].push_back(v);
        G[v].push_back(u);
    }
    memset(dp,0x3f,sizeof@H_502_16@ dp);
    for(int i=1;i<=n;i++@H_502_16@)
        dp[i][1]=G[i].size()-1@H_502_16@;
    dp[1][1]++@H_502_16@;
    
    dfs(1,1@H_502_16@);
    int ans=dp[1@H_502_16@][p];
    for(int i=2;i<=n;i++@H_502_16@)
        ans=min(ans,dp[i][p]+1@H_502_16@);
    cout<<ans<<@H_502_16@endl;
}

猜你在找的设计模式相关文章