题解 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 ...
随机推荐
- BZOJ 1201 [HNOI2005]数三角形:枚举 + 前缀和
题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=1201 题意: 有一个边长为n的正三角形网格,去掉其中一些线段,问你在这幅图中有多少个三角形 ...
- Jexus是一款Linux平台上的高性能WEB服务器和负载均衡网关
什么是Jexus Jexus是一款Linux平台上的高性能WEB服务器和负载均衡网关,以支持ASP.NET.ASP.NET CORE.PHP为特色,同时具备反向代理.入侵检测等重要功能.可以这样说,J ...
- codeforces 558A A. Lala Land and Apple Trees(水题)
题目链接: A. Lala Land and Apple Trees time limit per test 1 second memory limit per test 256 megabytes ...
- CodeForces - 123E Maze
http://codeforces.com/problemset/problem/123/E 题目翻译:(翻译来自: http://www.cogs.pw/cogs/problem/problem.p ...
- AtCoder Grand Contest 013 C:Ants on a Circle
题目传送门:https://agc013.contest.atcoder.jp/tasks/agc013_c 题目翻译 给你一个周长为\(L\)的圆,有\(N\)只蚂蚁在圆上爬,速度为一单位距离每秒. ...
- Elasticsearch官方安装
Installationedit Elasticsearch requires at least Java 8. Specifically as of this writing, it is reco ...
- 选中DataGrid的Cell而不是row
主要是针对DataGridCellsPresenter而不是SelectiveScrollingGrid,使用时DataGridRow应用这个style就可以了. <Style x:Key=&q ...
- border-radius实现圆弧阴影效果
1 原理 利用border-radius实现一个圆弧边的矩形,并添加box-shadow,然后放在目标元素的下方 demo: html <div class="demo1"& ...
- VMware vs openStack对比直观优势
openStack VS VMware直观优势:1.openStack设计架构开放.生态稳定 大型国际巨头公司支持及开发参与,功能版本迭代快,相对的VMware则是封闭的商业化系统.2.基于openS ...
- CF-816B
B. Karen and Coffee time limit per test 2.5 seconds memory limit per test 512 megabytes input standa ...