[ACM学习] 树形dp之换根

这篇具有很好参考价值的文章主要介绍了[ACM学习] 树形dp之换根。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

算法概述

[ACM学习] 树形dp之换根,学习

[ACM学习] 树形dp之换根,学习

总的来说:

题目描述:一棵树求哪一个节点为根时,XXX最大或最小

分为两步:1. 树形dp  2. 第二次dfs

问题引入

[ACM学习] 树形dp之换根,学习

如果暴力就是 O(n^2) ,

[ACM学习] 树形dp之换根,学习

当从1到2的时候,2及其子树所有的深度都减一,其它的点,所有的深度都加一。写成递推方程如下:

[ACM学习] 树形dp之换根,学习

代码

思路是:第一遍 dfs 遍历的时候先把以某一确定点为根的其它各点深度和算出来,再来看我们的状态转移方程,还需要各个点的大小值,所以在遍历的时候就把它给维护好。

[ACM学习] 树形dp之换根,学习

siz数组刚开始全为1

第二遍的时候,就是在用公式啦。

[ACM学习] 树形dp之换根,学习

在main 函数

[ACM学习] 树形dp之换根,学习

难点在于不同点之间怎么转移

[ACM学习] 树形dp之换根,学习

复杂度O(n)

例题

[ACM学习] 树形dp之换根,学习

按换根dp的思路,进行状态转移时

从1到2,原来到1的路径和ans[1] ,到2的路径和 ans[2] ,变化就是 :以2为子树的结点,路径长度少了1到2的长度,其它结点,路径长度多了1到2的长度

[ACM学习] 树形dp之换根,学习

sum[i] : 以 i 为子树的权值和

所以,方程上的变化就是:ans[2] = ans[1] - sum[2]*(1与2之间的路径长)+ (sum[1]-sum[2])*(1与2之间的路径长)

[ACM学习] 树形dp之换根,学习文章来源地址https://www.toymoban.com/news/detail-821919.html

代码

void dfs(int x,int fa){
    siz[x]=1;sum[x]=c[x];
    for(int i=head[x];i;i=edge[i].nex){
        int v=edge[i].to;
        if(v==fa)continue;
        dist[v]=dist[x]+edge[i].dis;
        dfs(v,x);
        siz[x]+=siz[v];
        sum[x]+=sum[v];
    }
    return ;
}
void dfs1(int x,int fa){
    for(int i=head[x];i;i=edge[i].nex){
        int v=edge[i].to;
        if(v==fa)continue;
        f[v]=f[x]-sum[v]*edge[i].dis+(tot-sum[v])*edge[i].dis;
    }
    return ;
}
dfs(1,0);
    for(int i=1;i<=n;i++){
        f[1]+=dist[i]*c[i];  //是把所有的点记录好到1的距离后,再全部来乘权值。
    }
    dfs1(1,0);
    ll ans=101010101000;
    for(int i=1;i<=n;i++){
        ans=min(ans,f[i]);
    }
    cout<<ans<<endl;
struct Edge{
    int nex,to,dis;
}edge[maxn<<1];
int siz[maxn],head[maxn],cnt,tot;
void add(int from,int to,int dis){
    edge[++cnt]={head[from],to,dis};
    head[from]=cnt;
    return ;
}

到了这里,关于[ACM学习] 树形dp之换根的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • AcWing算法学习笔记:动态规划(背包 + 线性dp + 区间dp + 计数dp + 状态压缩dp + 树形dp + 记忆化搜索)

    算法 复杂度 时间复杂度0(nm) 空间复杂度0(nv) 代码 算法 通过滚动数组对01背包朴素版进行空间上的优化 f[i] 与 f[i - 1]轮流交替 若体积从小到大进行遍历,当更新f[i, j]时,f[i - 1, j - vi] 已经在更新f[i, j - vi]时被更新了 因此体积需要从大到小进行遍历,当更新f[i, j]时,f[i - 1,

    2024年02月21日
    浏览(42)
  • 【每日一题Day267】LC834树中距离之和 | 换根dp

    树中距离之和【LC834】 给定一个无向、连通的树。树中有 n 个标记为 0...n-1 的节点以及 n-1 条边 。 给定整数 n 和数组 edges , edges[i] = [ai, bi] 表示树中的节点 ai 和 bi 之间有一条边。 返回长度为 n 的数组 answer ,其中 answer[i] 是树中第 i 个节点与所有其他节点之间的距离之和。

    2024年02月16日
    浏览(38)
  • 动态规划报告(树形DP+概率DP

    树形 DP,即在树上进行的 DP。由于树固有的递归性质,树形 DP 一般都是递归进行的。一般需要在遍历树的同时维护所需的信息 以一道题目为例 2022CCPC桂林站G Group Homework No, we don’t want group homework. It’s the place where 1+11 can be true. However, you are currently the leader of a group with three

    2024年02月12日
    浏览(46)
  • 动态规划-树形DP

    链接:https://www.acwing.com/problem/content/848/ 给定一颗树,树中包含 n n n 个结点(编号 1 ∼ n 1 sim n 1 ∼ n )和 n − 1 n-1 n − 1 条无向边。 请你找到树的重心,并输出将重心删除后,剩余各个连通块中点数的最大值。 重心定义:重心是指树中的一个结点,如果将这个点删除后,剩

    2024年02月08日
    浏览(38)
  • 动态规划之树形DP

    树形DP是指在“树”这种数据结构上进行的动态规划:给出一颗树,要求以最少的代价(或取得最大收益)完成给定的操作。通常这类问题规模比较大,枚举算法效率低,无法胜任,贪心算法不能求得最优解,因此需要用动态规划进行求解。 在树上做动态规划显得非常合适,

    2024年02月05日
    浏览(44)
  • 树形DP()

    Ural 大学有 N 名职员,编号为 1∼N。 他们的关系就像一棵以校长为根的树,父节点就是子节点的直接上司。 每个职员有一个快乐指数,用整数 Hi 给出,其中 1≤i≤N。 现在要召开一场周年庆宴会,不过,没有职员愿意和直接上司一起参会。 在满足这个条件的前提下,主

    2024年02月09日
    浏览(30)
  • 算法套路十九——树形DP

    树形 DP,即在树上进行的 DP。由于树固有的递归性质,这里的DP是指是一种通过把原问题分解为相对简单的子问题的方式求解复杂问题的方法,故虽然带有DP,但一般都是通过 递归 来进行。 给定一棵二叉树,你需要计算它的直径长度。一棵二叉树的直径长度是任意两个结点路

    2024年02月10日
    浏览(87)
  • 动态规划树形DP课后习题蓝桥舞会

      蓝桥舞会 题目描述 蓝桥公司一共有n名员工,编号分别为1~n。 他们之间的关系就像一棵以董事长为根的树,父节点就是子节点的直接上司。每个员工有一个快乐指数aj。 现蓝桥董事会决定举办一场蓝桥舞会来让员工们在工作之余享受美好时光,不过对于每个员工,他们都

    2024年02月21日
    浏览(43)
  • 算法基础复盘笔记Day11【动态规划】—— 区间DP、计数类DP、树形DP、记忆化搜索

    ❤ 作者主页:欢迎来到我的技术博客😎 ❀ 个人介绍:大家好,本人热衷于 Java后端开发 ,欢迎来交流学习哦!( ̄▽ ̄)~* 🍊 如果文章对您有帮助,记得 关注 、 点赞 、 收藏 、 评论 ⭐️⭐️⭐️ 📣 您的支持将是我创作的动力,让我们一起加油进步吧!!!🎉🎉 1. 题目

    2024年02月01日
    浏览(41)
  • acwing算法基础之动态规划--数位统计DP、状态压缩DP、树形DP和记忆化搜索

    暂无。。。 暂无。。。 题目1 :求a~b中数字0、数字1、…、数字9出现的次数。 思路:先计算1~a中每位数字出现的次数,然后计算1~b-1中每位数字出现的次数,两个相减即是最终答案。 那么,如何计算1~a中每位数字出现的次数呢? 首先,将a的每一位存入向量num中,例如a=123

    2024年02月04日
    浏览(49)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包