ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

树形DP和基环树

2021-02-17 15:05:22  阅读:203  来源: 互联网

标签:int max dfs 基环树 树形 DP 节点 dp


树形DP和基环树

目录


基础树形dp

  • 处理与树和图有关的dp
  • 天生的dp结构,以每棵子树为每个问题的子结构,在父亲节点合并
  • 巧妙地利用bfs和dfs序,可以优化问题,或得到好的解决方法
  • 可以考虑树上的数据结构来优化
  • 树行dp的时间复杂度要认真计算,部分问题要均摊时间复杂度
  • 一般设 f[u] 为以 u 为子树的最优价值或者方案数
  • 树形dp,在树结构上,求最值,求方案数等dp问题

栗题

给你一棵大小为 \(n\) 的树,求这棵树的最大独立集是多少。

最大独立集指的是一个最大的点集使得其中的点两两没有边相连

\(N\leq10^5\)

solution

没有上司的舞会??

也就是如果儿子节点选了,其父亲节点就不可以选;

枚举每个点选不选就好了,根据树上dp模型,从下往上转移就好了

状态

\(dp[i][0/1]\) 表示做完了 i 的子树,i 点是否选的最大独立集

转移

如果父亲节点不选孩子节点就可以任意选择

\[dp[i][0] = \sum_{j\in sons}max(dp[j][0],dp[j][1]) \]

如果父亲节点选了的话,孩子节点就不能选了

\[dp[i][0] = \sum_{j\in sons} dp[j][0] + 1 \]

node

void Dp{int u,int p){
  dp[u][0] = 1;
  dp[u][1] = 0;
  for (int i = head[u]; i; i = e[i].nxt){
       int v = e[i].v;
	   if(v == p)continue;
	   Dp(v, u);
	   dp[u][0] += dp[u][1];
	   dp[u][1] += max(dp[v][0],dp[v][1]);
   }
}

树的直径

给你一颗点数为 \(n\) 的树,让你求这棵树的直径是多少(求最长的两个点之间的距离)

\(N\leq100000\)

solution

  • 两遍dfs (似乎有次考试可以得部分分)

先随便找个点,跑一遍dfs找出最远的点,然后从这个最远的点再跑一遍dfs,跑到的最远的点就是树的直径(离每一个点最远的点肯定是直径的其中一个端点)

具体证明:树的直径证明方法

  • 树上dp思想

f[i]表示以 i 为根节点到子树的叶子节点最远距离

g[i]表示以 i 为根节点到子树的叶子节点次远距离

对于一个节点,它到叶子节点的最远距离和次远距离必定不一个样,最后只需要把根节点的最大值和次大值相加就是直径

转移:

\[if(f[i] < f[v] + e[i].w)~~ g[i] = f[i],f[i] = f[v] + e[i].w\\ \]

\[if(f[i] > f[v] + e[i].w且g[i] < f[v] + e[i].w)\\g[i] = f[v] + e[i].w \]

如果当前遍历的边大于最大值,就把最大值替换,次大值改为原来最大值,否则只更新次大值

void Dp(int x,int fa){
  for (int i = head[x]; i; i = e[i].nxt){
        int v = e[i].v;
		if(v == fa)continue;
		dp(v, x);
		if (f[x] < f[v] + e[i].w){
		    g[x] = f[x];
		    f[x] = f[v] + e[i].w;
		 }
		else if(g[x] < f[v] + e[i].w)
		     g[x] = f[v] + e[i].w;
        ans = max(ans,f[x] + g[x]);		 
  }
}

简单变式

  • 一棵无向树,结点为n \(\leq 10,000\),删除哪些结点可以使得新图中每一棵树结点数小于等于 \(n/2\) 也就是求重心
  • 树的覆盖集,求最少选几个点能覆盖所有边,也就是不存在一条边两边点都没被选(本质?)和最大点独立集互补
  • 最大权独立集?

几道栗题

给定一棵有 \(n\) 个点的树,以及 \(m\) 条树链,其中第 \(i\) 条树链的价值为 \(w_i\),请 选择一些没有公共点的树链,使得价值和最大

\(n,m\leq 1000\)

solution

当然是树形dp,设f(x)表示以x为根的子树内选取不相交的树链的价值和的最大值。枚举一条LCA为 x 的链(u, v, w),那么当前的价值就为w+除去u, v 路径上所有的点后,深度最小的点 f 的和

复杂度

\(O(M*N)\)

树链剖分优化:\(O(M*log(n)^2)\) 写一次挂一次

给出了一棵二叉树,点数为 \(n\),然后要求每个点和其左儿子和其右儿子三者两两之间颜色(红、绿、蓝)互不相同,求最多能有多少点被染成绿色

\(N\leq 10^5\)

solution

咋还是上司的舞会

\(f[i][0] ,f[i][1],f[i][2]\) 分别表示根是绿红蓝三种颜色时的最多/最少绿色的数量,按照约束转移就好了

给出一棵树,每个点上都有 \(W_i\) 的矿石,现在可以在一些点上设立仓库,每设立一个仓库,就要花费 \(K\) 的代价。最后每个点的代价如下计算,如果离他最近的点的距离为 \(dis\),则代价为\(

标签:int,max,dfs,基环树,树形,DP,节点,dp
来源: https://www.cnblogs.com/Arielzz/p/14408855.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有