首页 > 其他分享 >【树】树上动态规划

【树】树上动态规划

时间:2023-08-18 17:48:08浏览次数:38  
标签:动态 int dfs fa 树上 规划 街区 dp

目录

引入

考虑这样一个问题(P1352 没有上司的舞会):

一棵树,每个节点 \(i\) 都有价值 \(v_i\),对于每个子节点,不能和父节点同时选择,求最大价值和。

dp[x][0] 为在x的子树中表示i不取时值最大是多少。

dp[x][1] 为在x的子树中表示i取时值最大是多少。 选与不选两个状态,升维来保证没有后效性啦~

我们可以用这样一个函数(实际上是dfs):

void tdp(int x)
{
	for(int i = 0;i < tree[x].size();i++) //遍历儿子
	{
		int y = tree[x][i];
		tdp(y);
		dp[x][0] += max(dp[y][0], dp[y][1]);
		dp[x][1] += dp[y][0];
        }
}

树形dp

树上递推

在树上递推实现遍历整棵树。 这已经是惯常操作了呢~

先序遍历(关键词:到根)

例如:

求到根最远的节点?

后序遍历(关键词:子树)

例如:

如果某个职员的直接上司来参加舞会了,那么这个职员就无论如何也不肯来参加舞会了。

求直径(树上最长路径)

对于树上任意一点X,求出离P最远的点A,在找到离A最远的点B,A到B的路径就是树的直径。

使用反证法:证明过程点这里,感谢这位神犇 是你太懒了吧

这是一个例子

void dfs(int x, int fa)
{
	for(int i = 0;i < g[x].size();i++)
	{
		int y = g[x][i];
		if(y == fa) continue;
		dis[y] = dis[x] + w[x][i];
		dfs(y,x);
	}
}
int main()
{
	...
	dis[1] = 0;
	dfs(1, 0);
	int A = 0;
	for(int i = 1;i <= n;i++)
	{
		if(dis[i] > dis[A]) A = i;
	}
	dis[A] = 0;
	dfs(A,0);
	int B = 0;
	for(int i = 1;i <= n;i++)
	{
		if(dis[i] > dis[B]) B = i;
	}
	cout << dis[B];
	return 0;
}
    

换根DP法

我们来看这样一道题:市政服务大厅

D市共设有 \(N\) 个街区,编号 \(1\) ~ \(N\);建有 \(N−1\) 条双向道路,编号 \(1\) ~ \(N-1\),其中第 \(i\) 条道路长度 \(l_i\) ,连接了街区 \(a_i\) 与 \(b_i\) 。任意两个街区之间有且仅有一条路径。每个街区都常住有一定数量的市民,其中常住于街区 \(i\) 的市民共有 \(p_i\) 人。这里,市政服务大厅可选址于任意一个街区,但要使选址尽可能地优,就意味着所有常住市民到市政务府大厅的距离之和应尽可能地小(假设只考虑各个街区之间的距离,忽略同一个街区内部的距离)。

到x的总距离:

x子树外的人:到达 fa 后,一起走到x。sz[1] - sz[x]
x子树内的人:到达 fa 后,一起走到x。sz[1] - sz[x]

树上背包

Wiki

我们来看例题 P2014 选课

假设 dp[x][j] 表示x为根的子树分配j个名额的最大学分。

dp[x][...] 设为无穷小,dp[x][1] = a[x]

标准代码

void dfs(int x)
{
	for(int i = 0;i <= n;i++)
		dp[x][i] = -1e9;
	dp[x][1] = a[x];
	for(int i = 0;i < g[x].size();i++)
	{
		int y = g[x][i];
		dfs(y);
		for(int j = m;j >= 1;j--)
		{
			for(int k = 0;k < j;k++)
			{
				dp[x][j] = max(dp[x][j], dp[x][j-k] + dp[y][k]);
			}
		}
	}
}
int main()
{
	ios::sync_with_stdio(false);
	cin >> n >> m;
	m++;
	for(int i = 1;i <= n;i++)
	{
		int fa;
		cin >> fa >> a[i];
		g[fa].push_back(i);
	}
	dfs(0);
	cout << dp[0][m];
	return 0;
}
	

链式前向星

点:head[i] 表示第i个点的最后一条边。
边:next[i] 表示第i条边的上一个起点相同的边的序号。
\(\color{white}{\text{ . .: }}\)to[i] 第i条边的上一个起点相同的边的序号。

struct edge
{
    int to, w, nxt; // w是边长
}e[N*2];
int cnt, head[N];
void add(int x, int y, int z)
{
    e[++cnt] = (edge){y, z, head[x]};
    head[x] = cnt;
}
void dfs(int x, int fa)
{
    for(int i = head[x];i;i = e[i].nxt)
    {
        int y = e[i].to;
        if(y == fa) continue;
        dfs(y,x)
    }
}

标签:动态,int,dfs,fa,树上,规划,街区,dp
From: https://www.cnblogs.com/ghivan911/p/17637365.html

相关文章

  • 微信小程序动态绑定class样式类(三木运算)
    直接上代码,循环列表,根据选中状态显示不同的样式,active就是你在wxss文件里面创建的类名<view  class="{{item.select ? 'active':''}}" wx:for="{{itemList}}" wx:key="{{item.id}}">   {{item.name}}</view>在一个标签的class里添加{{}}模板语法,模板......
  • 一块迅为RK3568开发板规划的学习路线
    B站可以搜索教程......
  • ElementUI——vue2+element-ui 2.x的动态表格和表单
    前言一个基于vue2.x+element-ui2.x版本的项目,里面都是CURD的东西,但是前人并未封装组件,而是直接CV,现在要新增一个大模块的功能,就想着封装个组件,后面再基于这个组件对老项目进行改造;虽然是一个大模块,但是功能还是比较简单的,结构如下;内容?>这纯粹是个简单的DEMO,如果你需要......
  • 企业信息安全架构建设规划
    参考ISO27001、以网络安全法及等级保护2.0要求为基准,并结合业界最佳安全实践,从安全管理体系、安全技术体系、和安全运营体系三个方面,来实现公司整体信息安全水平提升。参考ISMS模型安全保障建设分阶段实施。实施过程渐进性、逐步性,根据先后缓急设计,初步将安全实施计划分为以下四......
  • Linuxy应用程序加载动态链接库的默认路径
    在Linux系统中,当应用程序执行时,系统会按照一定的规则去寻找动态链接库(也称为共享库或.so文件)。系统使用一组默认的搜索路径来查找这些库,以便在运行时正确加载所需的库。以下是Linux系统寻找动态链接库的一般规则:系统默认路径:Linux系统会在一组默认的路径中查找动态链接......
  • echart动态修改每个数据的label
    echart可以动态修改每个数据的label代码如下:data:type=='01'?this.yList[0].data.map((item,index)=>{console.log(item,'11111');this.yList[1].data.map((res,it)=>{if(index===it){......
  • 路径规划算法:基于郊狼算法的机器人路径规划算法- 附matlab代码
    ✅作者简介:热爱科研的Matlab仿真开发者,修心和技术同步精进,matlab项目合作可私信。......
  • 动态添加表单元素
    <html><head><title>动态添加表单元素</title></head><scriptlanguage="javascript">functionAddElement(mytype){varmytype,TemO=document.getElementById("add");varnewInput=document.createElement("......
  • 微信小程序:发布动态页面模板
    1前言由于功能需求,需要在小程序中开发社区打卡模块。打卡模块中上传发布的界面是必不可少的。于是利用flex布局设计了上传动态的页面。页面截图如下:由于是模板分享,这里也不做过多介绍了,通过代码来说明吧。页面主要有四个文件,分别是create.js、create.json、create.wxml、cre......
  • 如何找寻动态注册的方法
    安卓动态注册1.点击进入按F52.获得env对象,继续执行j_register方法3把int对象换成jni对象,load下头文件此时发现代码就清新多了......