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条高速公路,保证了任意两运城市之间都可以通过高速公 ...
随机推荐
- SpringBoot Application事件监听
SpringBoot Application共支持6种事件监听,按顺序分别是: ApplicationStartingEvent:在Spring最开始启动的时候触发 ApplicationEnviro ...
- hibernate注解 笔记
1.hibernate使用@where实现条件过滤功能 其里面只有一个参数clause,完整用法是: @Where(clause = "VALID_FLAG=1") 可以加在实体类 ...
- 5 ~ express ~ 连接数据库
1, 在schema 目录创建 users.js 文件,通过 mongoose 模块来操作数据库 2, 在定义 users 表结构之前,需要让应用支持或连接数据库 . 所以要在应用的入口文件 app ...
- java课程之团队开发冲刺阶段2.5
总结昨天进度: 1.昨天对课前提醒的基本框架已经搭好,剩下的就是对如何提醒进行设置 遇到的困难: 1.在一些细节地方,代码有点犯浑,将Preferences的文件写错了,导致在用switch开关得到时 ...
- python的常用序列
list1.list(obj)函数 obj可以为:元组(1,2,3),可迭代对象,字符串等转换换成数组类型2. 列表元素的添加 (1)list+[添加的元素] (2)list.append(添加元素) ...
- spring boot集成mybatis(2) - 使用pagehelper实现分页
Spring Boot 集成教程 Spring Boot 介绍 Spring Boot 开发环境搭建(Eclipse) Spring Boot Hello World (restful接口)例子 sp ...
- springboot-jar
预览 1.pom.xml <?xml version="1.0" encoding="UTF-8"?> <project xmlns=&quo ...
- 2020/2/6 PHP编程学习
今天把后台数据库处理好了,用了框架后真就是搬砖的一天..晚上继续刷题,明天把数据库处理完,这样一个商城框架就有了:
- 2020/2/1 PHP代码审计之变量覆盖漏洞
0x00 变量覆盖简介 变量覆盖是指变量未被初始化,我们自定义的参数值可以替换程序原有的变量值. 0x01 漏洞危害 通常结合程序的其他漏洞实现完整的攻击,比如文件上传页面,覆盖掉原来白名单的列表,导 ...
- c++ 模板练习2
#include "stdafx.h" #include <iostream> using namespace std; template<class T> ...