gym 101667 A -Broadcast Stations【树形dp】

A 树形dp

题目大意:

一棵5e3的树,可以选择一些点,放上基站,如果u上的基站价值为d,那么距离u小于等于d的点都会被覆盖,问使得整棵树被覆盖需要的最小价值。

题目分析

f [ u ] [ i ] f[u][i] f[u][i] 表示从 u这个点 ,向外最多能覆盖 到距离为i的点,且他的子树都被覆盖的最小价值。

那么我们考虑 f [ u ] [ i ] f[u][i] f[u][i] 可能是在u这个点建立了一个价值为i的基站,也可能是他的子树能够覆盖到 i+1

因此 我们还需要统计 u这个点 距离他的i的子树全被覆盖所需的最小价值

定义为 g[u][i]
g [ u ] [ i ] = ∑ g [ v ] [ i − 1 ] g[u][i] = \sum g[v][i-1] g[u][i]=g[v][i1]

所以我们考虑 f [ u ] [ i ] = m i n ( f [ v ] [ i + 1 ] − g [ v ] [ i ] , j ) + g [ u ] [ i + 1 ] f[u][i] = min(f[v][i+1] -g[v][i],j)+g[u][i+1] f[u][i]=min(f[v][i+1]g[v][i],j)+g[u][i+1]

f [ v ] [ i + 1 ] − g [ v ] [ i ] f[v][i+1] -g[v][i] f[v][i+1]g[v][i] 表示这个v这个点最多能往外延伸到i+1的距离,(也就是删去的v的子树)
这样在树上进行dp就可以了。

考虑边界情况
我们在计算 f[u][0] 的时候, 不能直接选择 j ,因为只有 u这一个点的时候也需要消耗 1的价值,所以我们特判 f[u][0]的情况

代码详情

#include <bits/stdc++.h>
using namespace std;
const int maxn = 5e3+50;
const int mod = 1e9+7;
const int inf = 0x3f3f3f3f;
vector<int>G[maxn];
int g[maxn][maxn];
int f[maxn][maxn]; 
int n;
void dfs(int u,int fa)
{
//	cout<<u<<" fa= "<<fa<<endl;
	for(int i=0;i<G[u].size();i++) 
	{
		
		int v = G[u][i];
		if(v!=fa)
		{
			dfs(v,u);
			for(int j=1;j<=n;j++)
			{
				g[u][j] += g[v][j-1];
			}
		}
	}
	f[u][n]= n; //表示 U点 覆盖所有点需要的价值,最大是n 
	g[u][0] =n; // 初始化g[u][0]  u的子树全覆盖的情况
	
	for(int i=n-1;i>=0;i--)
	{
		if(i!=0)
		f[u][i] = min(i+g[u][i+1],f[u][i+1]); //在某个位置新建一个基站 
		else if(i==0)
	  //特判=0的时候, f[u][0]表示子树都被覆盖,只覆盖u这个点的时候也需要1个 
		{
			f[u][i] = min(1+g[u][2],f[u][i+1]);
		 }
		for(int j=0;j<G[u].size();j++)
		{
			int v = G[u][j];
			if(v!=fa)
			{
				f[u][i] = min(f[u][i],f[v][i+1]-g[v][i]+g[u][i+1]);
			}
		} 
	} 
	
	g[u][0] =f[u][0];
	
	for(int i=1;i<=n;i++) g[u][i] = min(g[u][i],g[u][i-1]);
	//对于所有的子树,很显然满足这个关系。确保更新的值合理。 
	 
}
int main()
{
	scanf("%d",&n);
	memset(g,0,sizeof(g));
	memset(f,0,sizeof(f));
	for(int i=1;i<n;i++)
	{
		int u,v;
		scanf("%d%d",&u,&v);
		G[u].push_back(v);
		G[v].push_back(u);
	}
//	cout<<1<<endl;
	dfs(1,0);
//	cout<<2<<endl;
	printf("%d\n",g[1][0]); 
	return 0;
}
Python网络爬虫与推荐算法新闻推荐平台:网络爬虫:通过Python实现新浪新闻的爬取,可爬取新闻页面上的标题、文本、图片、视频链接(保留排版) 推荐算法:权重衰减+标签推荐+区域推荐+热点推荐.zip项目工程资源经过严格测试可直接运行成功且功能正常的情况才上传,可轻松复刻,拿到资料包后可轻松复现出一样的项目,本人系统开发经验充足(全领域),有任何使用问题欢迎随时与我联系,我会及时为您解惑,提供帮助。 【资源内容】:包含完整源码+工程文件+说明(如有)等。答辩评审平均分达到96分,放心下载使用!可轻松复现,设计报告也可借鉴此项目,该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的。 【提供帮助】:有任何使用问题欢迎随时与我联系,我会及时解答解惑,提供帮助 【附带帮助】:若还需要相关开发工具、学习资料等,我会提供帮助,提供资料,鼓励学习进步 【项目价值】:可用在相关项目设计中,皆可应用在项目、毕业设计、课程设计、期末/期中/大作业、工程实训、大创等学科竞赛比赛、初期项目立项、学习/练手等方面,可借鉴此优质项目实现复刻,设计报告也可借鉴此项目,也可基于此项目来扩展开发出更多功能 下载后请首先打开README文件(如有),项目工程可直接复现复刻,如果基础还行,也可在此程序基础上进行修改,以实现其它功能。供开源学习/技术交流/学习参考,勿用于商业用途。质量优质,放心下载使用。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值