写一篇题解,以纪念调了一个小时的经历(就是因为边的数组没有乘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)(二次扫描和换根法)的更多相关文章

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

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

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

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

  3. poj 3585 Accumulation Degree(二次扫描和换根法)

    Accumulation Degree 大致题意:有一棵流量树,它的每一条边都有一个正流量,树上所有度数为一的节点都是出口,相应的树上每一个节点都有一个权值,它表示从这个节点向其他出口可以输送的最大总 ...

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

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

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

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

  6. 【POJ3585】Accumulation Degree 二次扫描与换根法

    简单来说,这是一道树形结构上的最大流问题. 朴素的解法是可以以每个节点为源点,单独进行一次dp,时间复杂度是\(O(n^2)\) 但是在朴素求解的过程中,相当于每次都求解了一次整棵树的信息,会做了不少 ...

  7. POJ3585 Accumulation Degree(二次扫描与换根法)

    题目:http://poj.org/problem?id=3585 很容易想出暴力.那么就先扫一遍. 然后得到了指定一个根后每个点的子树值. 怎么转化利用一下呢?要是能找出当前点的父亲的 “ 不含当前 ...

  8. 【51Nod1405】树上距离和 二次扫描与换根法

    题目大意:给定一棵 N 个点的边权均为 1 的树,依次输出每个点到其他各个点的距离和. 题解:首先任意选定一个节点为根节点,比如 1,第一遍 dfs 遍历树求出子树大小.树上前缀和.第二遍 dfs 遍 ...

  9. poj - 3585(二次扫描与换根法)

    周末牛客挂了个更难的,这个简单一些 #include<iostream> #include<cstring> #include<cstdio> #include&l ...

随机推荐

  1. mysql八:ORM框架SQLAlchemy

    阅读目录 一 介绍 二 创建表 三 增删改查 四 其他查询相关 五 正查.反查 一 介绍 SQLAlchemy是Python编程语言下的一款ORM框架,该框架建立在数据库API之上,使用关系对象映射进 ...

  2. L84

    Hospital Noise May Disrupt Patient Improvement Many who need restorative rest the most might not be ...

  3. codeforces 706A A. Beru-taxi(水题)

    题目链接: A. Beru-taxi 题意: 问那个taxi到他的时间最短,水题; AC代码: #include <iostream> #include <cstdio> #i ...

  4. xgboost算法原理

    XGBoost是2014年3月陈天奇博士提出的,是基于CART树的一种boosting算法,XGBoost使用CART树有两点原因:对于分类问题,CART树的叶子结点对应的值是一个实际的分数,而非一个 ...

  5. 「LuoguP4995」「洛谷11月月赛」 跳跳!(贪心

    题目描述 你是一只小跳蛙,你特别擅长在各种地方跳来跳去. 这一天,你和朋友小 F 一起出去玩耍的时候,遇到了一堆高矮不同的石头,其中第 ii 块的石头高度为 h_ihi​,地面的高度是 h_0 = 0 ...

  6. jupyter-notebook重设项目工作路径

    一. . Anaconda Prompt 命令(方法没生效) 1 选择一个用于存放config文件的文件夹(先创建) 2 在cmd中进入该文件夹的路径 3在cmd中 输入​命令 jupyter not ...

  7. OGG 进程清除、重建

    背景描述:有时候OGG进程同步出现问题,症状某些进程起不来,而且问题一时半会儿解决不了.最简单的办法是:用数据泵初始化数据,OGG进程重建. 1.查看源端.目的端的进程状态. (作者OGG进程是正常的 ...

  8. 排名Top 16的Java实用类库

    (转载: http://www.hollischuang.com/archives/1606) github地址: https://github.com/liufeiSAP/javaStudy.git ...

  9. ASP.NET Core会议管理平台实战_4、参数校验、操作结果封装,注册参数配置

    登陆和注册之前,需要封装 前端参数的校验,ajax的封装 参数校验,创建公共的类 ,它是一个静态类 这样在调用的时候,直接一句话就可以了,这就是封装的好处 空字符串的校验 调用方式 EF的源码里面有这 ...

  10. 下拉选择select和复选框checkbox的状态的各种方式

    复选框的状态 <input name="ck" value=" " type="checkbox"  checked> 或者&l ...