【每日一题】14.Accumulation Degree(树形DP + 二次扫描)
补题链接:Here
一个树形水系,有 \(n\) 个结点,根结点称为源点,叶子结点称为汇点,每条边都有水量限制$C(x,y) \((\)x,y$ 为这条边的两个端点),源点单位时间流出的水量称为整个水系的流量,求以哪一个结点作为源点整个水系的流量最大。
首先得理解到这是一道“不定根”的树形DP问题,这类题目的特点是,给定一个树形结构,需要以每个结点为根进行一系列统计。我们一般通过两次扫描来求解此类问题:(也即:二次扫描与换根法)
- 第一次扫描时任选一个点为根,在“有根树”上执行一次“树形DP”,也就是在回溯时发生的、自底向上的状态转移。
- 第二次扫描,从刚才选出的根出发,对整棵树执行一次DFS,在每次递归前进行自上而下的推导,计算出“换根”之后的解。
首先,我们任选一个结点 root ,然后树形DP一下,求出 \(D_{root}\) 数组( \(D[i]\) 表示在以 \(i\) 为根的子树中流量的最大值)。然后设 \(f_x\) 表示以 \(x\) 为源点,流向整个水系的最大流量,则显然 \(f_{root} = D_{root}\) 假设 \(f_x\) 已经求出,考虑其子结点 \(y\) ,则 \(f[y]\) 包含两部分:
- 从 \(y\) 流向以 \(y\) 为根的子树的流量,已经计算出来。
- 从 \(y\) 沿着到父节点 \(x\) 的河道,进而流向水系中其他部分的流量。
由题意可知,从 \(x\) 流向 \(y\) 的流量为 \(min(D_y,c_{x,y})\) ,所以从 \(x\) 流向除 \(y\) 以外其他部分的流量分量是其两者之差:\(f_x - min(D_y,c_{x,y})\) 于是,把 \(y\) 作为源点,先从流到 \(x\),再流向其他部分的流量就是吧这个“差值”再与 \(c_{x,y}\) 取较小值后的结果
if(deg[x] == 1) \to f[y] = D[y] + c[x][y]
\]
这是一个由下而上的递推方程,所以我们可以通过一次DFS来完成
AC 代码
// Murabito-B 21/04/26
#include <bits/stdc++.h>
using namespace std;
#define fi first
#define se second
const int N = 2e5 + 5;
using pii = pair<int, int>;
vector<pii> g[N];
int dp[N], d[N], f[N];
void dfs(int u, int fa) {
for (int i = 0; i < g[u].size(); ++i) {
int v = g[u][i].fi, w = g[u][i].se;
if (v == fa) continue;
dfs(v, u);
if (d[v] == 1) dp[u] += w;
else
dp[u] += min(dp[v], w);
}
}
void dfs1(int u, int fa) {
f[u] = dp[u];
for (int i = 0; i < g[u].size(); ++i) {
int v = g[u][i].fi, w = g[u][i].se;
if (v == fa) continue;
if (d[v] == 1) {
dp[u] -= w;
dp[v] += min(dp[u], w);
} else {
dp[u] -= min(w, dp[v]);
dp[v] += min(w, dp[u]);
}
dfs1(v, u);
}
}
void solve() {
int n;
cin >> n;
for (int i = 1; i <= n; ++i) {
g[i].clear();
d[i] = dp[i] = f[i] = 0;
}
for (int i = 1; i < n; ++i) {
int u, v, w;
cin >> u >> v >> w;
g[u].push_back({v, w});
g[v].push_back({u, w});
d[u]++, d[v]++;
}
dfs(1, -1);
// f[1] = dp[1];
dfs1(1, -1);
int ans = 0;
for (int i = 1; i <= n; ++i) ans = max(ans, f[i]);
cout << ans << '\n';
}
int main() {
ios_base::sync_with_stdio(false), cin.tie(0), cout.tie(0);
int _;
for (cin >> _; _--;) solve();
return 0;
}
【每日一题】14.Accumulation Degree(树形DP + 二次扫描)的更多相关文章
- $Poj3585\ Accumulation Degree$ 树形$DP/$二次扫描与换根法
Poj Description 有一个树形的水系,由n-1条河道与n个交叉点组成.每条河道有一个容量,联结x与y的河道容量记为c(x,y),河道的单位时间水量不能超过它的容量.有一个结点是整个水系的发 ...
- poj3585 Accumulation Degree(树形dp,换根)
题意: 给你一棵n个顶点的树,有n-1条边,每一条边有一个容量z,表示x点到y点最多能通过z容量的水. 你可以任意选择一个点,然后从这个点倒水,然后水会经过一些边流到叶节点从而流出.问你最多你能倒多少 ...
- poj3585 树形dp 二次扫描,换根法模板题
#include<iostream> #include<cstring> #include<cstdio> #include<vector> using ...
- poj3585 Accumulation Degree[树形DP换根]
思路其实非常简单,借用一下最大流求法即可...默认以1为根时,$f[x]$表示以$x$为根的子树最大流.转移的话分两种情况,一种由叶子转移,一种由正常孩子转移,判断一下即可.换根的时候由頂向下递推转移 ...
- SPOJ 1479 +SPOJ 666 无向树最小点覆盖 ,第二题要方案数,树形dp
题意:求一颗无向树的最小点覆盖. 本来一看是最小点覆盖,直接一下敲了二分图求最小割,TLE. 树形DP,叫的这么玄乎,本来是线性DP是线上往前\后推,而树形DP就是在树上,由叶子结点状态向根状态推. ...
- CISP/CISA 每日一题 14
CISA 每日一题(答) 自动无人值守运行(LIGHTS-OUT)优势:1.信息系统运行成本的遏制/减少:2.持续运行(24/7):3.减少系统错误和中断次数. I/O 控制人员负责保证:1.批处理信 ...
- UVA 10859 Placing Lamppost 树形DP+二目标最优解的求解方案
题意:给定一个无向,无环,无多重边,要求找出最少的若干点,使得,每条边之中至少有一个点上有街灯.在满足上述条件的时候将还需要满足让两个点被选择的边的数量尽量多. 题解: 对于如何求解最小的节点数目这点 ...
- [树形DP]二叉苹果树
二 叉 苹 果 树 二叉苹果树 二叉苹果树 题目描述 有一棵苹果树,如果树枝有分叉,一定是分2叉(就是说没有只有1个儿子的结点) 这棵树共有N个结点(叶子点或者树枝分叉点),编号为1-N,树根编号一定 ...
- poj3417 Network 树形Dp+LCA
题意:给定一棵n个节点的树,然后在给定m条边,去掉m条边中的一条和原树中的一条边,使得树至少分为两部分,问有多少种方案. 神题,一点也想不到做法, 首先要分析出加入一条边之后会形成环,形成环的话,如果 ...
- 『战略游戏 最大利润 树形DP』
通过两道简单的例题,我们来重新认识树形DP. 战略游戏(luoguP1026) Description Bob喜欢玩电脑游戏,特别是战略游戏.但是他经常无法找到快速玩过游戏的办法.现在他有个问题.他要 ...
随机推荐
- Android学习day01【搭建Android Studio】
是Google开发的操作系统 Android开发是移动应用开发的表现形式之一 还有很多的开发形式,就不一一列举了 完整项目精简的开发流程 开发工具 Android studio(强烈建议) Andro ...
- 浅析MySQL代价模型:告别盲目使用EXPLAIN,提前预知索引优化策略
背景 在 MySQL 中,当我们为表创建了一个或多个索引后,通常需要在索引定义完成后,根据具体的数据情况执行 EXPLAIN 命令,才能观察到数据库实际使用哪个索引.是否使用索引.这使得我们在添加新索 ...
- chatgpt接口开发笔记3: 语音识别接口
chatgpt接口开发笔记3: 语音识别接口 1.文本转语音 1.了解接口参数 接口地址: POST https://api.openai.com/v1/audio/speech 下面是接口文档描述内 ...
- 吉特日化MES系统&各类化妆品检验标准汇总
在日化行业中,生产配料过程中,对产品的检验主要分为四大类: (1) 感官指标 (2) 理化指标 (3) 微生物指标 (4) 毒理指标 根据每个产品的不同,其指标会有所不同
- [ICPC2015WF] Tours
题目描述 The Arca Carania Mountain national park is opening up for tourist traffic. The national park ha ...
- [GDOIpj221B] 数列游戏
第二题 数列游戏 提交文件: sequence.cpp 输入文件: sequence.in 输出文件: sequence.out 时间空间限制: 1 秒, 256 MB 有一个长度为 \(n\) 的序 ...
- 将多个txt文件中的内容写在一个txt中的方法
import os filename='./train_data/img_' for i in range(1,19736): newfile=filename+str(i)+'.txt' if os ...
- python tkinter使用(九)
python tkinter使用(九) 本文主要讲下scrolledText中图片的插入,以及常见的错误. 使用Image.open来打开图片 使用ImageTk.PhotoImage()方法将图片转 ...
- ElasticSearch之虚拟内存
查看当前Linux系统中vm.max_map_count变量的值,命令如下: sysctl vm.max_map_count 执行结果的样例,如下: vm.max_map_count = 65530 ...
- ElasticSearch的日志配置
ElasticSearch默认情况下使用Log4j2来记录日志,日志配置文件的路径为$ES_HOME/config/log4j2.properties,配置方法见Log4j2的官方文档. 参考path ...