【POJ3585】Accumulation Degree 二次扫描与换根法
简单来说,这是一道树形结构上的最大流问题。
朴素的解法是可以以每个节点为源点,单独进行一次dp,时间复杂度是\(O(n^2)\)
但是在朴素求解的过程中,相当于每次都求解了一次整棵树的信息,会做了不少的重复工作。
对于一棵子树的孩子节点和根节点之间存在着最优解的某些关联,因此可以采用自顶向下的一次 dfs 遍历求得结果。
阶段:子树大小
状态:当前子树大小的情况下,最大的流量是多少
状态转移方程:见代码
代码如下
#include <cstdio>
#include <vector>
#include <memory.h>
using namespace std;
const int maxn=2e5+10;
int n,rt,d[maxn],f[maxn],deg[maxn];
struct node{
int to,w;
node(int x=0,int y=0):to(x),w(y){}
};
vector<node> G[maxn];
#define cls(a,b) memset(a,b,sizeof(a))
void init(){
cls(d,0);cls(f,0);cls(deg,0);
for(int i=1;i<=2e5;i++)G[i].clear();
}
inline void add_edge(int from,int to,int w){
G[from].push_back(node(to,w)),++deg[from];
G[to].push_back(node(from,w)),++deg[to];
}
void read_and_parse(){
scanf("%d",&n);
for(int i=1;i<n;i++){
int from,to,w;
scanf("%d%d%d",&from,&to,&w);
add_edge(from,to,w);
}
}
void dfs1(int u,int fa){
for(int i=0;i<G[u].size();i++){
int v=G[u][i].to,w=G[u][i].w;
if(v==fa)continue;
dfs1(v,u);
if(deg[v]==1)d[u]+=w;
else d[u]+=min(w,d[v]);
}
}
void dfs2(int u,int fa){
for(int i=0;i<G[u].size();i++){
int v=G[u][i].to,w=G[u][i].w;
if(v==fa)continue;
if(deg[u]==1)f[v]=d[v]+w;
else f[v]=d[v]+min(f[u]-min(w,d[v]),w);
dfs2(v,u);
}
}
void solve(){
rt=1;
dfs1(rt,0);
f[rt]=d[rt];//自顶向下需要初始化
dfs2(rt,0);
int ans=0;
for(int i=1;i<=n;i++)ans=max(ans,f[i]);
printf("%d\n",ans);
}
int main(){
int T;scanf("%d",&T);
while(T--){
init();
read_and_parse();
solve();
}
return 0;
}
【POJ3585】Accumulation Degree 二次扫描与换根法的更多相关文章
- POJ3585 Accumulation Degree(二次扫描与换根法)
题目:http://poj.org/problem?id=3585 很容易想出暴力.那么就先扫一遍. 然后得到了指定一个根后每个点的子树值. 怎么转化利用一下呢?要是能找出当前点的父亲的 “ 不含当前 ...
- poj3585 树形dp 二次扫描,换根法模板题
#include<iostream> #include<cstring> #include<cstdio> #include<vector> using ...
- 题解 poj3585 Accumulation Degree (树形dp)(二次扫描和换根法)
写一篇题解,以纪念调了一个小时的经历(就是因为边的数组没有乘2 phhhh QAQ) 题目 题目大意:找一个点使得从这个点出发作为源点,流出的流量最大,输出这个最大的流量. 以这道题来介绍二次扫描和换 ...
- poj 3585 Accumulation Degree(二次扫描和换根法)
Accumulation Degree 大致题意:有一棵流量树,它的每一条边都有一个正流量,树上所有度数为一的节点都是出口,相应的树上每一个节点都有一个权值,它表示从这个节点向其他出口可以输送的最大总 ...
- $Poj3585\ Accumulation Degree$ 树形$DP/$二次扫描与换根法
Poj Description 有一个树形的水系,由n-1条河道与n个交叉点组成.每条河道有一个容量,联结x与y的河道容量记为c(x,y),河道的单位时间水量不能超过它的容量.有一个结点是整个水系的发 ...
- 【51Nod1405】树上距离和 二次扫描与换根法
题目大意:给定一棵 N 个点的边权均为 1 的树,依次输出每个点到其他各个点的距离和. 题解:首先任意选定一个节点为根节点,比如 1,第一遍 dfs 遍历树求出子树大小.树上前缀和.第二遍 dfs 遍 ...
- poj - 3585(二次扫描与换根法)
周末牛客挂了个更难的,这个简单一些 #include<iostream> #include<cstring> #include<cstdio> #include&l ...
- [LuoguP1829]Crash的文明表格(二次扫描与换根+第二类斯特林数)
Solution: 由于 \[ x^m = \sum_{i=0}^m{~m~\choose i}{~x~\brace i}i! \] 将所求的式子化成这样,挖掘其性质,考虑是否能从儿子转移(或 ...
- poj3585 Accumulation Degree【树形DP】【最大流】
Accumulation Degree Time Limit: 5000MS Memory Limit: 65536K Total Submissions:3151 Accepted: 783 ...
随机推荐
- 个人博客地址: furur.xyz
趁着Hexo的热度,最近就买了域名,在GitHub Pages上搭了个人博客.也不是说博客园不好吧,毕竟在博客园三年多,也学到了不少东西,唯一要吐槽的,估计也就是后台管理不方便,markdown无即时 ...
- SpringBoot日记——分布式篇
思考:什么是分布式?什么是微服务? 一些概念:RPC-远程过程调用,某台机器想要调用另一台机器所需要的一种服务,及分布式的服务框架,比如dubbo或者SpringCloud. 铺天盖地的分布式互联网系 ...
- java垃圾回收诡异现象
在知乎上看到一篇提问,于是做了个实验帮助他解答,这里整理成一篇文章分享一下. 先看代码如下代码: /** * Created on 2017/12/16. * * -verbose:gc -XX:+U ...
- Jumpserver双机高可用环境部署笔记
之前在IDC部署了Jumpserver堡垒机环境,作为登陆线上服务器的统一入口.后面运行一段时间后,发现Jumpserver服务器的CPU负载使用率高达80%以上,主要是python程序对CPU的消耗 ...
- mariadb第二章-增删改
MariaDB 数据类型 MariaDB数据类型可以分为数字,日期和时间以及字符串值. 使用数据类型的原则:够用就行, 尽量使用范围小的,而不用大的 常用的数据类型 整数:int, bit 小数:de ...
- c++入门之关于cin,cout以及数据流的认识
- 个人博客作业Week2(9月30日)
一.是否需要有代码规范 1.这些规范都是官僚制度下产生的浪费大家的编程时间.影响人们开发效率, 浪费时间的东西. 这些规范并不是一开始就有的,也不是由某个人规定的,代码规范是程序员们在不断地编程实践过 ...
- Linux内核分析— —构造一个简单的Linux系统MenuOS(20135213林涵锦)
Linux内核分析— —构造一个简单的Linux系统MenuOS 实验内容 Linux内核的启动过程,从start_kernel到init进程启动 使用实验楼的虚拟机打开shell cd LinuxK ...
- phpcms全站搜索
这篇博客已经移至http://www.cnblogs.com/nuanai/p/8028562.html中~~~~~~
- redis的优缺点
优点: 1 读写性能优异 2 支持数据持久化,支持AOF和RDB两种持久化方式 3 支持主从复制,主机会自动将数据同步到从机,可以进行读写分离. 4 数据结构丰富:除了支持string类型的value ...