ICode9

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

树形DP

2022-08-03 22:04:18  阅读:191  来源: 互联网

标签:int 路径 dfs 树形 节点 DP d1


树形 DP,即在树上进行的 DP。
由于树固有的递归性质,树形 DP 一般都是递归进行的。

树的最长路径

题目描述
给定一个含有 n 个节点的 树,以及树中每条边的权值 wedgei。
现需要在树中找出一条路径,使得该路径上所有边的权值之和最大。

思路:
记录以i为根节点的子树中,从子树某个节点到i的最长路和次长路。
那么以经过i的最长边就是最长路+次长路。
而且很明显可以递归求解。

闫氏DP分析法
状态表示—集合\(f_{1,i}\),\(f_{2,i}\): 以节点 i 为根的子树中,从子树某个节点到 i 的最长路为 f1,次长路为 f2
状态表示—属性: 路径长度的最大值 Max
状态计算.......
代码:

#include <bits/stdc++.h>
#define endl '\n'
#define int long long
#define pii pair<int, int>
#define pll pair<int, int>
#define ull unsigned long long
using namespace std;
const int N = 10010, M = N * 2;
int n;
int to[M], w[M], pre[M], h[N], idx;
void add(int a, int b, int c)
{
    to[idx] = b, w[idx] = c, pre[idx] = h[a], h[a] = idx++;
}
int ans = 0;
int dfs(int u, int fa)
{
    int d1 = 0, d2 = 0;
    for (int i = h[u]; i != -1; i = pre[i])
    {
        int j = to[i];
        if (j == fa)
            continue;
        int d = dfs(j, u)+w[i];
        if (d >= d1)
            d2 = d1, d1 = d;
        else if (d > d2)
            d2 = d;
    }
    ans = max(ans, d1 + d2);
    return d1;
}
void solve()
{
    memset(h, -1, sizeof h);
    cin >> n;
    for (int i = 0; i < n-1; i++)
    {
        int a, b, c;
        cin >> a >> b >> c;
        add(a, b, c), add(b, a, c);
    }

    dfs(1, -1);
    cout << ans << endl;
}

signed main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    int t = 1;
    // cin >> t;
    while (t--)
        solve();
    return 0;
}

树的中心 换根DP

题意:
给定一棵树,树中包含 n 个结点(编号1~n)和 n−1 条无向边,每条边都有一个权值。
请你在树中找到一个点,使得该点到树中其他结点的最远距离 最近

思路:
思考一下:求一个节点的 最远距离 时,会有几种路径呢:

  1. 从当前节点往下,直到子树中某个节点的最长路径

  2. 从当前节点往上走到其父节点,再从其父节点出发且不回到该节点的最长路径

引入 换根DP 的思想
换根DP 一般分为三个步骤:

  1. 指定任意一个根节点
  2. 一次dfs遍历,统计出当前子树内的节点对当前节点的贡献
  3. 一次dfs遍历,统计出当前节点的父节点对当前节点的贡献,然后合并统计答案

我们先 dfs 一遍,预处理出当前子树对于根的最大贡献(距离)和 次大贡献(距离)

处理 次大贡献(距离) 的原因是:
如果 当前节点 是其 父节点子树 的 最大路径 上的点。此时 父节点子树 的 最大贡献 不能算作对该节点的贡献,就要使用次大贡献

因为我们的路径是 简单路径(不能 走回头路)

然后我们再 dfs 一遍,求解出每个节点的父节点对他的贡献(即每个节点往上能到的最远路径

两者比较,取一个 max 即可

代码:


主要参考:一只野生彩色铅笔
https://www.acwing.com/user/myspace/index/55909/

标签:int,路径,dfs,树形,节点,DP,d1
来源: https://www.cnblogs.com/kingwz/p/16548828.html

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

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

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

ICode9版权所有