POJ 3585 Accumulation Degree【换根DP】
传送门:http://poj.org/problem?id=3585
题意:给定一张无根图,给定每条边的容量,随便取一点使得从这个点出发作为源点,发出的流量最大,并且输出这个最大的流量。
思路:最近开始做树形DP这部分的题,发现存图部分不是太会,这道题需要用到邻接表存图,不熟悉的朋友可以见我的另一篇博客:https://blog.csdn.net/weixin_43820920/article/details/98610704
言归正传,这道题算是换根DP的裸题了,就是先随便找一个点做为根结点(u),从这个根结点(u)出发,依次找到其叶子结点
的父亲结点的最大流量,然后在依次从下往上更新,即可得到,该根结点(u)的最大流量。但是题意并没有给我们指定结点,所
以这就需要我们的换根了。我们可以依次枚举该根结点的孩子结点(v),将它的孩子节点(v)假设为符合题意的结点,依次更新。
设为以x为根的子树中,把x作为源点,从x发出的流量的最大值,这个用dfs扫描一次即可得出。 状态转移方程:
设为以x作为整棵树的根得出的答案,也只要dfs再次扫描一次。 第一次dfs是以u为根扫描的所以即是
状态转移方程:
这个dfs是从上往下更新。更新结点时,由于其父节点
已知(并且假设其父结点不为叶节点),先假设
去除
这条子树时为
,则此时的
,即是上面的状态转移方程
代码:
#include<iostream>
#include<string.h>
#include<cstdio>
using namespace std;
const int maxn = 200005;
int n;
int tot;
struct node
{
int to;
int next;
int w;
};
node edges[maxn << 1];
int deg[maxn];//结点的深度
int head[maxn];
//以x为根的子树中,把x作为源点,从x发出的流量的最大值
int d[maxn];
//以x作为整棵树的根得出的答案
int f[maxn];
//邻接表存图
void add_edges(int u, int v, int w)
{
edges[++tot].to = v;
edges[tot].w = w;
edges[tot].next = head[u];
head[u] = tot;
}
void init()
{
memset(deg, 0, sizeof(deg));
memset(head, 0, sizeof(head));
memset(f, 0, sizeof(f));
memset(d, 0, sizeof(d));
tot = 0;
}
void dfs1(int root, int fa)
{
d[root] = 0;
for(int i = head[root]; i; i = edges[i].next)
{
int v = edges[i].to;
if(v == fa)
continue;
else
{
dfs1(v, root);
if(deg[v] == 1)
d[root] += edges[i].w;
else
d[root] += min(d[v], edges[i].w);
}
}
}
void dfs2(int root, int fa)
{
for(int i = head[root]; i; i = edges[i].next)
{
int v = edges[i].to;
if(v == fa)
continue;
else
{
if(deg[root] == 1)
{
f[v] = d[v] + edges[i].w;
}
else
{
f[v] = d[v] + min(f[root] - min(edges[i].w, d[v]), edges[i].w);
}
dfs2(v, root);
}
}
}
int main()
{
int t;
scanf("%d", &t);
while(t--)
{
int n;
scanf("%d", &n);
init();
for(int i = 1; i < n; i++)
{
int x, y, v;
scanf("%d%d%d", &x, &y, &v);
add_edges(x, y, v);
add_edges(y, x, v);
deg[x]++;
deg[y]++;
}
if(n == 0 || n == 1)
{
cout << 1 << endl;
continue;
}
else
{
int root = 1;
dfs1(root, 0);//随便取一个点做为根结点
f[root] = d[root];
dfs2(root, 0);
int ans = 0;
for(int i = 1; i <= n; i++)
ans = max(ans, f[i]);
cout << ans << endl;
}
}
}
POJ 3585 Accumulation Degree【换根DP】的更多相关文章
- poj3585 Accumulation Degree(换根dp)
传送门 换根dp板子题(板子型选手 题意: 一棵树确定源点和汇点找到最大的流量(拿出一整套最大瘤板子orz ; int head[maxn],tot; struct node { int nt,to; ...
- poj 3585 Accumulation Degree(二次扫描和换根法)
Accumulation Degree 大致题意:有一棵流量树,它的每一条边都有一个正流量,树上所有度数为一的节点都是出口,相应的树上每一个节点都有一个权值,它表示从这个节点向其他出口可以输送的最大总 ...
- POJ3585:Accumulation Degree(换根树形dp)
Accumulation Degree Time Limit: 5000MS Memory Limit: 65536K Total Submissions: 3425 Accepted: 85 ...
- POJ 3585 Accumulation Degree
二次扫描与换根法 用于解决无根树,对于每一个节点作为根时都要统计 做法: 1.先以任意一个节点为根,做树形DP,保存每个节点的DP值 2.然后自上而下dfs,对于每个节点考虑以他为根的最大值 #inc ...
- POJ 3585 Accumulation Degree 题解
题面 一句话题意:找一个点使得,使得从这个点出发作为源点,发出的流量最大,输出这个最大的流量 这道题是换根法+二次扫描的模板: 首先若确定1为原点,那么可以写出dp方程:当v的度是1时, g[u]+= ...
- [算法学习] 换根dp
换根dp 一般来说,我们做题的树都是默认 \(1\) 为根的.但是有些题目需要计算以每个节点为根时的内容. 朴素的暴力:以每个点 \(u\) 作为 \(root\) 暴力dfs下去,复杂度\(O(n^ ...
- [BZOJ4379][POI2015]Modernizacja autostrady[树的直径+换根dp]
题意 给定一棵 \(n\) 个节点的树,可以断掉一条边再连接任意两个点,询问新构成的树的直径的最小和最大值. \(n\leq 5\times 10^5\) . 分析 记断掉一条边之后两棵树的直径为 \ ...
- 2018.10.15 NOIP训练 水流成河(换根dp)
传送门 换根dp入门题. 貌似李煜东的书上讲过? 不记得了. 先推出以1为根时的答案. 然后考虑向儿子转移. 我们记f[p]f[p]f[p]表示原树中以ppp为根的子树的答案. g[p]g[p]g[p ...
- 换根DP+树的直径【洛谷P3761】 [TJOI2017]城市
P3761 [TJOI2017]城市 题目描述 从加里敦大学城市规划专业毕业的小明来到了一个地区城市规划局工作.这个地区一共有ri座城市,<-1条高速公路,保证了任意两运城市之间都可以通过高速公 ...
随机推荐
- Codeforces 392 B Blown Garland
题意:输入是由连续的RYGB和字符!组成的字符串,R代表红灯,Y代表黄灯,G代表绿灯,B代表蓝灯.简而言之,就是给定的字符串保证了下标对4取余相同的灯颜色都相同,但是有的地方为‘!’代表这个灯坏了,然 ...
- tx2的一些系统命令
查看TX2 ubuntu系统版本命令:https://blog.csdn.net/zhengxiangwen/article/details/60324802 sudo uname --m
- 个人网站一步一步搭建——(20)成功在本地IIS运行
昨天网站都做完了,今天发布.然后在IIS运行成功了. 遇到了很多问题 发布了不低于10次 头都晕了. 问题1:之前写了很多调试代码 console.log(); 慢慢删除完,. 问题2:vue 不能 ...
- bzoj1415 NOI2005聪聪和可可
%%%http://hzwer.com/2819.html 先各种暴力搞出来p[x][y](从x到y下一个最近应该到达的位子) 然后就记忆化搜索??(雾) #include<bits/stdc+ ...
- java: 集合collection
collection是集合层次结构中的根接口,一些集合允许重复元素,而其他集合不允许. 有些collection是有序的,而另一些是无序的. JDK不提供此接口的任何直接实现:它提供了更具体的子接口的 ...
- HTML条件注释判断<!--[if IE] ![endif]-->
很多网页中会见到这样的代码: <!--[if IE 7]> <![endif]--> /*或者*/ <!--[if lt IE 9]> <![endif]-- ...
- 8.scrapy的第一个实例
[目标]要完成的任务如下: ※ 创建一个 Scrap项目.※ 创建一个 Spider来抓取站点和处理数据.※ 通过命令行将抓取的内容导出.※ 将抓取的内容保存的到 MongoDB数据库.======= ...
- salt教程1-理解saltstack
https://docs.saltstack.com/en/getstarted/system/index.html 1 基本介绍 通过观察它的实际运行,你可以大致理解salt如何工作.这意味着,在控 ...
- Java 14 都要来了,为什么还有这么多人固守Java8?
作者:刘欣 从Java 9开始,Java版本的发布就让人眼花缭乱了. 每隔6个月,都会冒出一个新版本出来,Java 10 , Java 11, Java 12, Java 13, 到2020年3月份, ...
- js保留的关键字
js保留的关键字 break else new var case finally return void catch for switch while continue function this w ...