题目 题意: 有一棵 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
关注
打赏
最近更新
- 深拷贝和浅拷贝的区别(重点)
- 【Vue】走进Vue框架世界
- 【云服务器】项目部署—搭建网站—vue电商后台管理系统
- 【React介绍】 一文带你深入React
- 【React】React组件实例的三大属性之state,props,refs(你学废了吗)
- 【脚手架VueCLI】从零开始,创建一个VUE项目
- 【React】深入理解React组件生命周期----图文详解(含代码)
- 【React】DOM的Diffing算法是什么?以及DOM中key的作用----经典面试题
- 【React】1_使用React脚手架创建项目步骤--------详解(含项目结构说明)
- 【React】2_如何使用react脚手架写一个简单的页面?