poj3585 Accumulation Degree(树形dp,换根)
题意:
给你一棵n个顶点的树,有n-1条边,每一条边有一个容量z,表示x点到y点最多能通过z容量的水。
你可以任意选择一个点,然后从这个点倒水,然后水会经过一些边流到叶节点从而流出。问你最多你能倒多少容量的水
示例:
A(1)= 11 + 5 + 8 = 24
详情:1-> 2 11
1-> 4-> 3 5
1-> 4-> 5 8(因为1-> 4的容量为13)
A(2)= 5 + 6 = 11
详细信息:2-> 1-> 4-> 3 5
2-> 1-> 4-> 5 6
A(3)= 5
详细信息:3-> 4-> 5 5
A(4)= 11 + 5 + 10 = 26
详细信息:4-> 1-> 2 11
4-> 3 5
4-> 5 10
A(5)= 10
详细信息:5-> 4-> 1-> 2 10
因为A(4)最大,所以最多能倒26容量的水
题解:
我们可以先随便找一个点当作树根,我这里选择节点1
然后我们可以dfs一遍去获取每一个节点能从它的子节点中的叶节点流出水的量,用数组d来保存
求出来所有节点的d值之后,这个时候1节点的流量就是d[1],也就是A(1)=d[1]
这个时候我们求A(2)
我们可以先将A(1)减去2节点来的流量
ans=dp[1]-min(1->2,d[2])
然后这个ans和1->2这一条边取最小值,就是不属于2的子节点的其他叶节点能到2节点的流量
这个时候再加上d[2]就可以了
- /*
- 这就是一个树形dp(也就是依据树的边进行dp)
- */
- #include<stdio.h>
- #include<string.h>
- #include<math.h>
- #include<algorithm>
- #include<iostream>
- using namespace std;
- #define mem(a) memset(a,0,sizeof(a))
- #define mem__(a) memset(a,-1,sizeof(a))
- typedef long long ll;
- const int maxn=200010;
- const int INF=0x3f3f3f3f;
- const double blo=(1.0+sqrt(5.0))/2.0;
- const double eps=1e-8;
- /*
- child[x]表示以1为根节点情况下,以x为根的子树上能到达x节点上的最大流
- 然后你知道dp[x]和child[to]之后就可以求出来dp[to]
- 因为dp[x]减去从to这个子树上来的流量就是其他节点到x的流量,那么就可以知道其他节点到to节点的流量
- dp[to]=child[to]+min(dp[x]-min(e[i].dis,child[to]),e[i].dis);
- */
- int n,head[maxn],child[maxn],du[maxn],dp[maxn],num;
- struct Edge{
- int next,to,dis;
- }e[2*maxn];
- void add_edge(int from,int to,int dis){
- e[++num].next=head[from];
- e[num].to=to;
- e[num].dis=dis;
- head[from]=num;
- }
- int dfs_child(int x,int fa)
- {
- int sum=0;
- for(int i=head[x];i!=-1;i=e[i].next)
- {
- int to=e[i].to;
- if(to==fa) continue;
- sum+=min(dfs_child(to,x),e[i].dis);
- }
- child[x]=sum;
- if(du[x]==1) return e[head[x]].dis;
- else return child[x];
- }
- void dfs(int x,int fa)
- {
- for(int i=head[x];i!=-1;i=e[i].next)
- {
- int to=e[i].to;
- if(to==fa) continue;
- /*
- 要加这个特判,因为如果我们的1点是一个叶节点(就是我们挑选了一个叶节点为根开始遍历),那么这个叶节点的子节点
- 的dp值就需要是加上child[to],然后再加上父节点的边权,你画个图理解一下
- 如果不加这个判断会卡下面这个数据,你按照这个数据画个图
- 1
- 3
- 1 2 1
- 2 3 1
- */
- if(du[x]==1) dp[to]=child[to]+e[i].dis;
- else
- dp[to]=child[to]+min(dp[x]-min(e[i].dis,child[to]),e[i].dis);
- dfs(to,x);
- }
- }
- int main()
- {
- int t;
- scanf("%d",&t);
- while(t--)
- {
- scanf("%d",&n);
- num=0;
- mem(child);
- mem(dp);
- mem(du);
- mem__(head);
- for(int i=1;i<n;++i)
- {
- int x,y,z;
- scanf("%d%d%d",&x,&y,&z);
- du[x]++;
- du[y]++;
- add_edge(x,y,z);
- add_edge(y,x,z);
- }
- dp[1]=dfs_child(1,-1);
- dfs(1,-1);
- int maxx=0;
- for(int i=1;i<=n;++i)
- maxx=max(maxx,dp[i]);
- printf("%d\n",maxx);
- }
- return 0;
- }
poj3585 Accumulation Degree(树形dp,换根)的更多相关文章
- poj3585 Accumulation Degree[树形DP换根]
思路其实非常简单,借用一下最大流求法即可...默认以1为根时,$f[x]$表示以$x$为根的子树最大流.转移的话分两种情况,一种由叶子转移,一种由正常孩子转移,判断一下即可.换根的时候由頂向下递推转移 ...
- $Poj3585\ Accumulation Degree$ 树形$DP/$二次扫描与换根法
Poj Description 有一个树形的水系,由n-1条河道与n个交叉点组成.每条河道有一个容量,联结x与y的河道容量记为c(x,y),河道的单位时间水量不能超过它的容量.有一个结点是整个水系的发 ...
- bzoj 3743 [Coci2015]Kamp——树形dp+换根
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=3743 树形dp+换根. “从根出发又回到根” 减去 “mx ” . 注意dfsx里真的要改那 ...
- 树形dp换根,求切断任意边形成的两个子树的直径——hdu6686
换根dp就是先任取一点为根,预处理出一些信息,然后在第二次dfs过程中进行状态的转移处理 本题难点在于任意割断一条边,求出剩下两棵子树的直径: 设割断的边为(u,v),设down[v]为以v为根的子树 ...
- [题解](树形dp/换根)小x游世界树
2. 小x游世界树 (yggdrasi.pas/c/cpp) [问题描述] 小x得到了一个(不可靠的)小道消息,传说中的神岛阿瓦隆在格陵兰海的某处,据说那里埋藏着亚瑟王的宝藏,这引起了小x的好奇,但当 ...
- POJ3585:Accumulation Degree(换根树形dp)
Accumulation Degree Time Limit: 5000MS Memory Limit: 65536K Total Submissions: 3425 Accepted: 85 ...
- 题解 poj3585 Accumulation Degree (树形dp)(二次扫描和换根法)
写一篇题解,以纪念调了一个小时的经历(就是因为边的数组没有乘2 phhhh QAQ) 题目 题目大意:找一个点使得从这个点出发作为源点,流出的流量最大,输出这个最大的流量. 以这道题来介绍二次扫描和换 ...
- POJ3585 Accumulation Degree (树形DP-二次扫描与换根)
本题属于不定根的树形DP,若以每个节点为根求解一次,复杂度太高,所以可以用换根的技巧. d[u]表示以u为根向下可以流的最大流量,这个是比较好求的,直接遍历到叶子节点,由子节点信息更新父节点.然后进行 ...
- POJ3585 Accumulation Degree【换根dp】
题目传送门 题意 给出一棵树,树上的边都有容量,在树上任意选一个点作为根,使得往外流(到叶节点,叶节点可以接受无限多的流量)的流量最大. 分析 首先,还是从1号点工具人开始$dfs$,可以求出$dp[ ...
随机推荐
- 【SpringBoot1.x】SpringBoot1.x 缓存
SpringBoot1.x 缓存 文章源码 JSR107 Java Caching 定义了 5 个核心接口,分别为: CachingProvider 定义了创建.配置.获取.管理和控制多个 Cache ...
- 【C++】《C++ Primer 》第十章
第十章 泛型算法 一.概述 因为它们实现共同的操作,所以称之为"算法".而"泛型",指的是它们可以操作在多种容器类型上. 泛型算法并不直接操作容器,而是遍历由两 ...
- Flutter 布局类组件:简介
前言 布局类组件都会包含一个或多个子组件,不同的布局类组件对子组件排版(layout)方式不同. 我们知道,Element树才是最终的绘制树,Element树是通过Widget树来创建的(通过Widg ...
- Educational Codeforces Round 102 (Rated for Div. 2)
比赛地址 A(水题) 题目链接 题目: 给出一个数组\(a\)并能进行一个操作使得数组元素更改为数组任意其他两元素之和,问是否可以让数组元素全部小于等于\(d\) 解析: 排序后判断最大值是否小于等于 ...
- Writing in the science: Introducion
1.what makes a good writing? 2.what makes a good writer? 1) have something to say 2) logical thinkin ...
- Hbase Region合并
业务场景: Kafka+SparkStreaming+Hbase由于数据大量的迁移,再加上业务的改动,新增了很多表,导致rerigon总数接近4万(36个节点) 组件版本: Kafka:2.1.1 S ...
- oracle 12C单实例打PSU
前提: oracle不管打什么样的补丁,readme都是很好的参考资料. Oracle每季度都会更新一个最新的PSU,现在12.1.0.2.0的最新的PSU是Patch 26925311. 由于今天白 ...
- SAP系统跨平台字符编码转换
SAP系统在进行了夸平台的迁移,可能会遇到操作系统层文件编码不同,导致SAP系统无法识别或者乱码的问题.例如SAP系统从AIX平台迁移到linux平台,SAP应用服务器的编码会发生变化,从4102变化 ...
- MongoDB查询优化--explain,慢日志
引入 与Mysql数据库一样,MongoDB也有自己的查询优化工具,explain和慢日志 explain shell命令格式 db.collection.explain().<method(. ...
- 核酸检测:让我明白AQS原理
春节越来越近了,疫情也越来越严重,但挡不住叫练携一家老小回老家(湖北)团聚的冲动.响应国家要求去我们做核酸检测了. 独占锁 早上叫练带着一家三口来到了南京市第一医院做核酸检测,护士小姐姐站在医院门口拦 ...