补题链接: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]\) 包含两部分:

  1. 从 \(y\) 流向以 \(y\) 为根的子树的流量,已经计算出来。
  2. 从 \(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] + min(f[x] - min(D[y],c[x][y]) - 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 + 二次扫描)的更多相关文章

  1. $Poj3585\ Accumulation Degree$ 树形$DP/$二次扫描与换根法

    Poj Description 有一个树形的水系,由n-1条河道与n个交叉点组成.每条河道有一个容量,联结x与y的河道容量记为c(x,y),河道的单位时间水量不能超过它的容量.有一个结点是整个水系的发 ...

  2. poj3585 Accumulation Degree(树形dp,换根)

    题意: 给你一棵n个顶点的树,有n-1条边,每一条边有一个容量z,表示x点到y点最多能通过z容量的水. 你可以任意选择一个点,然后从这个点倒水,然后水会经过一些边流到叶节点从而流出.问你最多你能倒多少 ...

  3. poj3585 树形dp 二次扫描,换根法模板题

    #include<iostream> #include<cstring> #include<cstdio> #include<vector> using ...

  4. poj3585 Accumulation Degree[树形DP换根]

    思路其实非常简单,借用一下最大流求法即可...默认以1为根时,$f[x]$表示以$x$为根的子树最大流.转移的话分两种情况,一种由叶子转移,一种由正常孩子转移,判断一下即可.换根的时候由頂向下递推转移 ...

  5. SPOJ 1479 +SPOJ 666 无向树最小点覆盖 ,第二题要方案数,树形dp

    题意:求一颗无向树的最小点覆盖. 本来一看是最小点覆盖,直接一下敲了二分图求最小割,TLE. 树形DP,叫的这么玄乎,本来是线性DP是线上往前\后推,而树形DP就是在树上,由叶子结点状态向根状态推. ...

  6. CISP/CISA 每日一题 14

    CISA 每日一题(答) 自动无人值守运行(LIGHTS-OUT)优势:1.信息系统运行成本的遏制/减少:2.持续运行(24/7):3.减少系统错误和中断次数. I/O 控制人员负责保证:1.批处理信 ...

  7. UVA 10859 Placing Lamppost 树形DP+二目标最优解的求解方案

    题意:给定一个无向,无环,无多重边,要求找出最少的若干点,使得,每条边之中至少有一个点上有街灯.在满足上述条件的时候将还需要满足让两个点被选择的边的数量尽量多. 题解: 对于如何求解最小的节点数目这点 ...

  8. [树形DP]二叉苹果树

    二 叉 苹 果 树 二叉苹果树 二叉苹果树 题目描述 有一棵苹果树,如果树枝有分叉,一定是分2叉(就是说没有只有1个儿子的结点) 这棵树共有N个结点(叶子点或者树枝分叉点),编号为1-N,树根编号一定 ...

  9. poj3417 Network 树形Dp+LCA

    题意:给定一棵n个节点的树,然后在给定m条边,去掉m条边中的一条和原树中的一条边,使得树至少分为两部分,问有多少种方案. 神题,一点也想不到做法, 首先要分析出加入一条边之后会形成环,形成环的话,如果 ...

  10. 『战略游戏 最大利润 树形DP』

    通过两道简单的例题,我们来重新认识树形DP. 战略游戏(luoguP1026) Description Bob喜欢玩电脑游戏,特别是战略游戏.但是他经常无法找到快速玩过游戏的办法.现在他有个问题.他要 ...

随机推荐

  1. Element的安装与基本使用

    一.什么是Element? Element是饿了么团队研发的一套为开发者与设计师等准备的基于Vue2.0的桌面端组件库,使开发人员可以快速拼凑出一套页面 组件:组成网页的部件,例如:超链接,按钮,图片 ...

  2. k8s~envoy上添加wasm插件

    先查看这篇文章k8s~envoy的部署 当在Kubernetes中使用Envoy的WASM过滤器时,WASM过滤器会与Envoy一起部署在同一个Pod中,并与后端服务进行通信.以下是一个简单的关系图示 ...

  3. ClickHouse(17)ClickHouse集成JDBC表引擎详细解析

    目录 JDBC 建表 用法示例 JDBC表函数 资料分享 参考文章 JDBC 允许CH通过JDBC连接到外部数据库. 要实现JDBC连接,CH需要使用以后台进程运行的程序 clickhouse-jdb ...

  4. [NOI online22提高A] 丹钓战

    题目描述 有 \(n\) 个二元组 \((a_i, b_i)\),编号为 1 到 n. 有一个初始为空的栈 SS,向其中加入元素 \((a_i, b_i)\) 时,先不断弹出栈顶元素直至栈空或栈顶元素 ...

  5. gridlayout

    <?xml version="1.0" encoding="utf-8"?> <GridLayout xmlns:android=" ...

  6. LCIS最长公共上升子序列!HDU-1423

    This is a problem from ZOJ 2432.To make it easyer,you just need output the length of the subsequence ...

  7. 组合式api-ref引用子组件、dom元素, defineExpose的使用

    和vue2一样,我们有时候希望父组件能够调用子组件中的方法.属性.那么就要用到ref. 然后你会发现,根本调用不了子组件中的方法"sonSayHi",如下图: 原因: 使用

  8. 华企盾DSC在苹果电脑上申请审批没有通知

    由于系统通知这里没有允许DSC通知,开启后即可.系统偏好设置-通知与专注模式-通知 ​

  9. 使用 PostgreSQL 16.1 + Citus 12.1 作为多个微服务的分布式 Sharding 存储后端

    在本教程中,我们将使用 PostgreSQL 16.1 + Citus 12.1 作为多个微服务的存储后端,演示此类集群的样例设置和基本操作. Citus 12.1 实验环境设置 Docker 快速启 ...

  10. Win10遇到服务器启动失败 80端口被占用如何解决

    Win10提示"服务器启动失败,80端口被占用"怎么办?具体解决方法如下 步骤如下: 1.以管理员身份运行cmd; 2.输入:net stop http 注:如果提示是否真的需要停 ...