其他分享
首页 > 其他分享> > 树形DP和基环树

树形DP和基环树

作者:互联网

树形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,跑到的最远的点就是树的直径(离每一个点最远的点肯定是直径的其中一个端点)

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

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