前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >洛谷P1272 重建道路 树形dp

洛谷P1272 重建道路 树形dp

作者头像
用户2965768
发布2019-07-11 10:38:42
3460
发布2019-07-11 10:38:42
举报
文章被收录于专栏:wymwym

f[ i ][ j ] 表示 i 为根节点选择 j 个点要去掉的最小边数。

一开始初始化所有边都去掉,只剩下本身一个点,值等于度数,根据是否为根结点加减一。

然后dp时-1是应为要加上 u 到 v 的一条边,dp表示要去掉的边,则要去掉的一条边则减一 

代码语言:javascript
复制
//洛谷P1272 重建道路
//树形dp 
#include <bits/stdc++.h>
using namespace std;
const int maxn = 155;
struct N{
	int nxt,v;
}ed[maxn<<2];
int dp[maxn][maxn],du[maxn];
int head[maxn],cnt,n,p,ans=0x7ffffff;
void add(int u,int v){
	cnt++;
	ed[cnt].v = v;
	ed[cnt].nxt = head[u];
	head[u] = cnt; 
}
void dfs(int u,int fa){
	dp[u][1] = du[u] - (fa!=0);//u为根节点选择i个点要去掉的最小边数 
	for(int v,i=head[u];i;i=ed[i].nxt){
		v = ed[i].v;
		if(v==fa)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[u][k]+dp[v][j-k]-1);
				//一开始把所有边都删了,连接v u 还需要加上一条边
				//所以去掉的边就少一条 	
			}
		}
		
	}
	ans = min(ans,dp[u][p]+(fa!=0)); //不是根结点 还要去掉父结点和自己的连线 
}
int main()
{		
	
	scanf("%d %d",&n,&p);
	for(int i=1;i<n;i++){
		int u,v;
		scanf("%d %d",&u,&v);
		du[u]++; du[v]++;
		add(u,v);	add(v,u);
	}
	memset(dp,0x3f,sizeof(dp));
	dfs(1,0);
	printf("%d",ans);
	return 0;
}
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2019年07月10日,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档