题解 poj3585 Accumulation Degree (树形dp)(二次扫描和换根法)
写一篇题解,以纪念调了一个小时的经历(就是因为边的数组没有乘2 phhhh QAQ)
题目大意:找一个点使得从这个点出发作为源点,流出的流量最大,输出这个最大的流量。
以这道题来介绍二次扫描和换根法
作为一道不定根的树形DP,如果直接对每个点进行DP,可能时间会炸掉
但是,优秀的二次换根和扫描法可以再O(n^2)内解决问题。
二次扫描的含义:(来自lyd 算法竞赛进阶指南)
第一次扫描:任选一个节点为根节点(我会选1)在树上进行树形DP,在回溯时,从儿子节点向父节点(从底向上)进行状态转移
第二次扫描:从刚才选的根出发,对树进行dfs,在每次递归前进行自顶向下的推导,计算"换根"后的解
在第一次扫描时,我们可以算出以节点u为根的子树中,从u流向其子树的最大流量

在第二次扫描时,我们通过dfs,可以自上而下的求出以节点u为根,从u流向整个流域(其子树)的最大流量

当我们从节点u到节点v时,已经求出F[u],而从u到v的流量为min(D[v],w(u,v)),所以从u流向v的其他部分的流量就是F[u]-min(D[v],w(u,v)),所以拿它再跟w(u,v)取min
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#define R register int
using namespace std;
const int N=;
struct edge{
int v,nxt,w;
}e[N<<];
int t,n,ans,cnt;
int d[N],f[N],fir[N],deg[N];
bool vis[N]; inline void add(int u,int v,int w) {e[++cnt].v=v,e[cnt].w=w,e[cnt].nxt=fir[u],fir[u]=cnt;} inline int g()
{
R ret=,fix=; register char ch;
while(!isdigit(ch=getchar())) fix=ch=='-'?-:fix;
do ret=(ret<<)+(ret<<)+(ch^); while(isdigit(ch=getchar()));
return ret*fix;
} void dp(int u)
{
vis[u]=true,d[u]=;
for(R i=fir[u];i;i=e[i].nxt)
{
R v=e[i].v; if(vis[v]) continue;
dp(v);
if(deg[v]==) d[u]+=e[i].w;
else d[u]+=min(d[v],e[i].w);
}
} void dfs(int u)
{
vis[u]=true;
for(R i=fir[u];i;i=e[i].nxt)
{
R v=e[i].v; if(vis[v]) continue;
if(deg[u]==) f[v]=d[v]+e[i].w;
else f[v]=d[v]+min(f[u]-min(d[v],e[i].w),e[i].w);
dfs(v);
}
} int main()
{
t=g();
while(t--)
{
memset(vis,false,sizeof(vis));
memset(fir,,sizeof(fir));
memset(deg,,sizeof(deg)); ans=,cnt=;
n=g();
if(n==||n==) {putchar(''),putchar('\n');continue;}
for(R i=;i<n;i++) {R u=g(),v=g(),w=g(); add(u,v,w),add(v,u,w); deg[u]++,deg[v]++;}
R rt=;
dp(rt); f[rt]=d[rt];
memset(vis,false,sizeof(vis));
dfs(rt);
for(R i=;i<=n;i++) ans=max(ans,f[i]);
printf("%d\n",ans);
}
return ;
}
(我太菜了。。。。QAQ)
如有错误,恳请您指正(我太菜了);如有不理解,可留言,我会尽量回复。。。(高中生(逃)。。)
by Jackpei 2019.2.22
题解 poj3585 Accumulation Degree (树形dp)(二次扫描和换根法)的更多相关文章
- $Poj3585\ Accumulation Degree$ 树形$DP/$二次扫描与换根法
Poj Description 有一个树形的水系,由n-1条河道与n个交叉点组成.每条河道有一个容量,联结x与y的河道容量记为c(x,y),河道的单位时间水量不能超过它的容量.有一个结点是整个水系的发 ...
- poj3585 树形dp 二次扫描,换根法模板题
#include<iostream> #include<cstring> #include<cstdio> #include<vector> using ...
- poj 3585 Accumulation Degree(二次扫描和换根法)
Accumulation Degree 大致题意:有一棵流量树,它的每一条边都有一个正流量,树上所有度数为一的节点都是出口,相应的树上每一个节点都有一个权值,它表示从这个节点向其他出口可以输送的最大总 ...
- poj3585 Accumulation Degree(树形dp,换根)
题意: 给你一棵n个顶点的树,有n-1条边,每一条边有一个容量z,表示x点到y点最多能通过z容量的水. 你可以任意选择一个点,然后从这个点倒水,然后水会经过一些边流到叶节点从而流出.问你最多你能倒多少 ...
- poj3585 Accumulation Degree[树形DP换根]
思路其实非常简单,借用一下最大流求法即可...默认以1为根时,$f[x]$表示以$x$为根的子树最大流.转移的话分两种情况,一种由叶子转移,一种由正常孩子转移,判断一下即可.换根的时候由頂向下递推转移 ...
- 【POJ3585】Accumulation Degree 二次扫描与换根法
简单来说,这是一道树形结构上的最大流问题. 朴素的解法是可以以每个节点为源点,单独进行一次dp,时间复杂度是\(O(n^2)\) 但是在朴素求解的过程中,相当于每次都求解了一次整棵树的信息,会做了不少 ...
- POJ3585 Accumulation Degree(二次扫描与换根法)
题目:http://poj.org/problem?id=3585 很容易想出暴力.那么就先扫一遍. 然后得到了指定一个根后每个点的子树值. 怎么转化利用一下呢?要是能找出当前点的父亲的 “ 不含当前 ...
- 【51Nod1405】树上距离和 二次扫描与换根法
题目大意:给定一棵 N 个点的边权均为 1 的树,依次输出每个点到其他各个点的距离和. 题解:首先任意选定一个节点为根节点,比如 1,第一遍 dfs 遍历树求出子树大小.树上前缀和.第二遍 dfs 遍 ...
- poj - 3585(二次扫描与换根法)
周末牛客挂了个更难的,这个简单一些 #include<iostream> #include<cstring> #include<cstdio> #include&l ...
随机推荐
- 如何设置android studio让程序运行在真机中
1.Run——>Edit Configurations... 2.运行
- 【译】在ES6中如何优雅的使用Arguments和Parameters
原文地址:how-to-use-arguments-and-parameters-in-ecmascript-6 ES6是最新版本的ECMAScript标准,而且显著的改善了JS里的参数处理.我们现在 ...
- erlang的map基本使用
maps 适用于需要在运行时改变数据结构(record则不行)的场景,可以动态增加key 数据量不宜过大,具体多大没有实际数据, maps from_list 如果list表很长,则相应的耗时时间会 ...
- codeforces 706C C. Hard problem(dp)
题目链接: C. Hard problem time limit per test 1 second memory limit per test 256 megabytes input standar ...
- 解决 maps to localhost, but this does not map back to the address
修改 /etc/ssh/ssh_config vim /etc/ssh/ssh_config GSSAPIAuthentication no
- Oracle表空间维护总结
1. 概念:表空间:最大的逻辑存储文件,与物理上的一个或多个数据文件对应,每个数据库至少拥有一个表空间,表空间的大小等于构成表空间的所有数据文件的大小总和,用于存储用户在数据库中存储的所有内容. 2. ...
- python list列表sort、sorted、reverse排序
列表排序:sort是修改原列表,sorted提供原列表的一个有序副本 li=[2,1,4,5,0]li.sort() #默认从小到大print li结果:[0, 1, 2, 4, 5] li=[2,1 ...
- JIRA 破解文件研究(Win 7环境)
最近再次回来研究 Win 7 下的 JIRA,按网上的很多方法去尝试,竟然无法正常安装! 经过几次的弯路尝试,终究还是成功了. 嗯,有必要总结一下: 发觉网上的很多破解方法都太老!不管是什么原因,在6 ...
- 32.Docker安装MongoDb
从hub.docker.com上去找镜像 阿里云的国内的镜像地址 填上去之后,然后重启下docker就可以了 docker images列出本地的镜像 拉取mango的镜像 运行这个镜像 docker ...
- VMware S/4 HANA OP 1511虚拟机下载,64G内存限制解决方案
http://www.itpub.net/thread-2057212-1-1.html S4 HANA OP 1511 Scale Out