【每日一题】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喜欢玩电脑游戏,特别是战略游戏.但是他经常无法找到快速玩过游戏的办法.现在他有个问题.他要 ...
随机推荐
- day2-JS基础&流程控制
typora-root-url: img 自增自减运算符 1.基本使用 内置提供 ++.--运算符 是用于将变量本身进行加1或者减1操作 // 1.基本使用 var i = 10; i++;//等价于 ...
- 自学 --day9---js中的数学操作和时间日期
typora-copy-images-to: media 一.数学处理 1.Math常用API 圆周率 Math.PI // 3.1415926535 生成随机数 Math.random() 生成的是 ...
- .net中优秀依赖注入框架Autofac看一篇就够了
Autofac 是一个功能丰富的 .NET 依赖注入容器,用于管理对象的生命周期.解决依赖关系以及进行属性注入.本文将详细讲解 Autofac 的使用方法,包括多种不同的注册方式,属性注入,以及如何使 ...
- cocos2d-Js 各类碰撞检测
这里总结一下点.圆.矩形之间的简单碰撞检测算法(矩形不包括旋转状态) 点和圆的碰撞检测: 1.计算点和圆心的距离 2.判断点与圆心的距离是否小于圆的半径 isCollision: function(p ...
- 华企盾DSC无缝替换其它加密软件两种方法
有源码和大型图纸的使用第一种方案 第一种: 1.把DSCClient.exe和DSCService.exe添加到竞品的加密软件进程中,配置允许打开加密文件,加密类型不加密 2.安装DSC客户端后扫描加 ...
- 手写滑动同步滚动进度条jq插件
因需要一种滑动显示内容,并且带可拖动的进度条,即下面这种效果 找了很多插件,总有地方不能满足需求.于是决定自己手写,下面为完整源码: swiper.js 1 $.swiperCalculator = ...
- 2023Java最新面试题整理 - Java 基础
大家好,我是闲者,最近正在考虑找新工作,进行面试,但是工作时间比较久了,很多基础知识都很模糊,所以得复习下,顺便做下记录,也便于大家参考. 以下为大纲,后期会定期更新 当面试涉及Java基础时,通常会 ...
- libGDX游戏开发之AssetManager资源管理(十)
libGDX游戏开发之AssetManager资源管理(十) libGDX系列,游戏开发有unity3D巴拉巴拉的,为啥还用java开发?因为我是Java程序员emm-国内用libgdx比较少,多数情 ...
- RV1126 DSI 调试
一.基本信息 开发板:RV1126 linux版本:4.19.111 显示屏:HX070JGI50(7寸) 显示器分别率:1024 * 600 二.MIPI协议 连接示意图(图片来源,正点资料) MI ...
- 一个小巧、快速、轻量级的 .NET NoSQL 嵌入式数据库
前言 今天给大家分享一个小巧.快速.轻量级的 .NET NoSQL 嵌入式数据库:LiteDB.本篇文章主要是介绍LiteDB和在.NET中如何使用. LiteDB介绍 LiteDB 是一个小巧.快速 ...