您当前的位置: 首页 > 

先求一个导

暂无认证

  • 0浏览

    0关注

    291博文

    0收益

  • 0浏览

    0点赞

    0打赏

    0留言

私信
关注
热门博文

dp学习笔记7 换根dp不会捏

先求一个导 发布时间:2022-04-28 15:05:19 ,浏览量:0

题目 题意: 有一棵 n 个点的树,每条边有一流量限制。令某一个点为根节点,向根节点灌水,最终从叶子节点流出的水量和为这一个点的最大流量,请求出每个点的最大流量。 思路: f[i]:表示以i为根的子树最多能承载的流量(当以1为根时). f[i] = Sigma min(f[son] + a[i][son]),流量受到两个方面的限制,一是儿子这棵子树能承载的最大流量,二是这条边的最大流量。 一遍dfs即可求出f[1]. 设置v[i]:表示换根后以i为根的子树的流量改变量. 接下来我们考虑换根的影响,即把根从一个点换成另一个点的影响。 每个点的当前流量即f[i]+v[i],原来的值+改变的值,自然是现在的值。 对于i的儿子son,如果把根从i换成son,产生什么变化呢? 首先son为根的子树的情况不变,还是f[son]。 而以i为根又不在son为根的子树中的节点就变了,他们现在变成一个整体,怎么统计这一块的承载流量值呢?用f[i]+v[i] - min(f[son],a[i][son])即可,因为以i为根的子树的流量值已经统计好了,换根以后son是根,不和其他人玩了,把son的影响消除掉。这个值与a[i][son]比较一下即可,因为流量要同时受到边和子树的限制。 最后输出f[i] + v[i]即可。 这里注意一下的是,叶子的承载能力是无限的,所以这里要特判一下。 而且还有一种特殊情况,如果当前节点i换根后是叶子,他的承载能力也要设置为无穷,也就是说v[son] = a[i][son],否则那个值是0,会出错。 时间复杂度: O(n) 代码:

#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define OldTomato ios::sync_with_stdio(false),cin.tie(nullptr),cout.tie(nullptr)
#define fir(i,a,b) for(int i=a;i>n;
   for(int i=0;i>x>>y>>z;
   	  add(x,y,z); add(y,x,z);
   }
   dfs1(1,0);
   // for(int i=1;i            
关注
打赏
1662037414
查看更多评论
0.0405s