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条高速公路,保证了任意两运城市之间都可以通过高速公 ...
随机推荐
- (四)requests模块的cookies和代理操作
基于requests模块的cookie操作 引言:有些时候,我们在使用爬虫程序去爬取一些用户相关信息的数据(爬取某个人“人人网”个人主页数据)时,如果使用之前requests模块常规操作时,往往达不到 ...
- 小程序分享H5页面
1.在要分享的按钮上写一个跳转 <navigator url="../invite1/invite1"> <button class="invite_b ...
- P2057 [SHOI2007]善意的投票 / [JLOI2010]冠军调查
P2057 [SHOI2007]善意的投票 / [JLOI2010]冠军调查 拿来练网络流的qwq 思路:如果i不同意,连边(i,t,1),否则连边(s,i,1).好朋友x,y间连边(x,y,1)(y ...
- windows driver 定时器的使用
#include < Ntifs.h> #pragma warning(disable:4995) #pragma comment(lib, "Ntoskrnl.lib" ...
- 2 ~ express ~ 模板引擎的配置与使用
一,创建应用 (一),创建应用,监听端口 var express = require('express') // 创建app应用 var app = express() app.listen(3000 ...
- Day3-T1
原题目 Describe:暴力出奇迹 [ 注意步长0.5!] code: #include<bits/stdc++.h> using namespace std; inline int r ...
- .NET CORE AutoMapper使用
1.通过nuget安装AutoMapper,版本是7.0.1, 安装AutoMapper.Extensions.Microsoft.DependencyInjection 版本是4.0.1 不是以上 ...
- Codeforces Round #604 (Div. 2) 部分题解
链接:http://codeforces.com/contest/1265 A. Beautiful String A string is called beautiful if no two con ...
- 2020/1/31 PHP代码审计之文件包含漏洞
0x00 文件包含简介 文件包含漏洞的产生原因是在通过引入文件时,引用的文件名,用户可控,由于传入的文件名没有经过合理的校检,或者校验被绕过,从而操作了预想之外的文件,就可能导致意外的文件泄露甚至恶意 ...
- Sequence Models Week 2 Emojify
Emojify! Welcome to the second assignment of Week 2. You are going to use word vector representation ...