当前位置 : 主页 > 手机开发 > 其它 >

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

来源:互联网 收集:自由互联 发布时间:2021-06-22
/* 还是树形的背包,dp[u][j]表示u的子树里,切割出一个大小为j的包含u的联通块的代价 那么dp[u][j]按照常规的依赖背包转移即可 初始状态时dp[u][1],切割掉u的所有儿子的代价 注意本题需
/* 还是树形的背包,dp[u][j]表示u的子树里,切割出一个大小为j的包含u的联通块的代价 那么dp[u][j]按照常规的依赖背包转移即可 初始状态时dp[u][1],切割掉u的所有儿子的代价 注意本题需要特别讨论u是根和非根的情况,即非根的儿子是度数-1,但是最后以这个点作为中心时就要加上这个减掉的1 */
#include<bits/stdc++.h>
#include<vector>
using namespace std;
#define N 205
vector<int>G[N];
int dp[N][N],n,p;//dp[u][j]表示u子树下取大小为j的联通块的代价 
void dfs(int u,int pre){
    for(int i=0;i<G[u].size();i++){
        int v=G[u][i];
        if(v==pre)continue;
        dfs(v,u);
        for(int j=p;j>=1;j--)
            for(int k=1;k<j;k++)
                dp[u][j]=min(dp[u][j],dp[v][k]+dp[u][j-k]-1);
    }
}
int main(){
    cin>>n>>p;
    for(int i=1;i<n;i++){
        int u,v;cin>>u>>v;
        G[u].push_back(v);
        G[v].push_back(u);
    }
    memset(dp,0x3f,sizeof dp);
    for(int i=1;i<=n;i++)
        dp[i][1]=G[i].size()-1;
    dp[1][1]++;
    
    dfs(1,1);
    int ans=dp[1][p];
    for(int i=2;i<=n;i++)
        ans=min(ans,dp[i][p]+1);
    cout<<ans<<endl;
}
网友评论