Time Limit: 5000MS | Memory Limit: 65536K | |
Total Submissions:3151 | Accepted: 783 |
Description
Trees are an important component of the natural landscape because of their prevention of erosion and the provision of a specific ather-sheltered ecosystem in and under their foliage. Trees have also been found to play an important role in producing oxygen and reducing carbon dioxide in the atmosphere, as well as moderating ground temperatures. They are also significant elements in landscaping and agriculture, both for their aesthetic appeal and their orchard crops (such as apples). Wood from trees is a common building material.
Trees also play an intimate role in many of the world's mythologies. Many scholars are interested in finding peculiar properties about trees, such as the center of a tree, tree counting, tree coloring. A(x) is one of such properties.
A(x) (accumulation degree of node x) is defined as follows:
- Each edge of the tree has an positive capacity.
- The nodes with degree of one in the tree are named terminals.
- The flow of each edge can't exceed its capacity.
- A(x) is the maximal flow that node x can flow to other terminal nodes.
Since it may be hard to understand the definition, an example is showed below:
A(1)=11+5+8=24 | ||
Details: | 1->2 | 11 |
1->4->3 | 5 | |
1->4->5 | 8(since 1->4 has capacity of 13) | |
A(2)=5+6=11 | ||
Details: | 2->1->4->3 | 5 |
2->1->4->5 | 6 | |
A(3)=5 | ||
Details: | 3->4->5 | 5 |
A(4)=11+5+10=26 | ||
Details: | 4->1->2 | 11 |
4->3 | 5 | |
4->5 | 10 | |
A(5)=10 | ||
Details: | 5->4->1->2 | 10 |
The accumulation degree of a tree is the maximal accumulation degree among its nodes. Here your task is to find the accumulation degree of the given trees.
Input
The first line of the input is an integer T which indicates the number of test cases. The first line of each test case is a positive integer n. Each of the following n - 1 lines contains three integers x, y, z separated by spaces, representing there is an edge between node x and node y, and the capacity of the edge is z. Nodes are numbered from 1 to n.
All the elements are nonnegative integers no more than 200000. You may assume that the test data are all tree metrics.
Output
For each test case, output the result on a single line.
Sample Input
1
5
1 2 11
1 4 13
3 4 5
4 5 10
Sample Output
26
Source
题意:
给定一棵不定根的树。水流从根流出(源点),流向叶子节点(汇点),每条边有一个容量。整个水系的流量定义为源点流出的水量。求哪个点作为源点时,整个水洗的流量最大,输出这个最大值。
思路:
用d[x]表示以x为根的子树中,把x作为源点,从x出发流向子树的流量最大值。比较暴力的方法是枚举源点,每次都计算他的流量。时间时O(n^2)显然不行。
下面介绍一种“二次扫描与换根法”
代替源点的枚举,就可以在O(N)时间内解决整个问题。
首先任选一个点root,求出以他为根是的d数组。
设f[x]表示把x作为源点,流向整个水系,流量的最大值。显然 f[root] = d[root]
当f[x]被求出时,考虑他的子节点y,f[y]包含两部分:1.从y流向以y为根的子树的流量,即d[y]中的值。 2.从y沿着父节点x的河道,进而流向水系中其他部分的流量。
x作为源点的总流量为f[x], 从x流向y的流量为min(d[y], c(x,y)),所以从x流向除y以外其他部分的流量就是二者之差。再与c(x,y)取最小值就可以得到以y作为源点,先流到x在流向其他部分的流量。那么得到f[y]就是把源点从x换成y之后,流量的计算结果。
//#include <bits/stdc++.h>
#include<iostream>
#include<cmath>
#include<algorithm>
#include<stdio.h>
#include<cstring>
#include<vector>
#include<map> #define inf 0x3f3f3f3f
using namespace std;
typedef long long LL; int n;
const int maxn = 2e5 + ;
int head[maxn], cnt = , d[maxn], deg[maxn], f[maxn];
struct edge{
int x, y;
int nxt;
int c;
}edge[maxn * ]; void init()
{
memset(head, -, sizeof(head));
cnt = ;
memset(d, , sizeof(d));
memset(deg, , sizeof(deg));
} void addedge(int x, int y, int w)
{
edge[cnt].x = x;
edge[cnt].y = y;
edge[cnt].c = w;
edge[cnt].nxt = head[x];
head[x] = cnt++;
edge[cnt].x = y;
edge[cnt].y = x;
edge[cnt].c = w;
edge[cnt].nxt = head[y];
head[y] = cnt++;
deg[x]++;
deg[y]++;
} void dfs(int rt, int fa)
{
int ans = ;
for(int i = head[rt]; i != -; i = edge[i].nxt){
int y = edge[i].y;
if(y == fa){
continue;
}
if(deg[y] == ){
ans += edge[i].c;
}
else{
dfs(y, rt);
ans += min(d[y], edge[i].c);
}
}
d[rt] = ans;
return ;
} void dp(int x, int fa)
{
for(int i = head[x]; i != -; i = edge[i].nxt){
int y = edge[i].y;
if(edge[i].y == fa)continue;
if(deg[x] == ){
f[y] = d[y] + edge[i].c;
}
else{
f[y] = d[y] + min(f[x] - min(d[y], edge[i].c), edge[i].c);
}
dp(y, x);
}
} int main()
{
int t;
scanf("%d", &t);
while(t--){
init();
scanf("%d", &n);
for(int i = ; i < n - ; i++){
int x, y, w;
scanf("%d%d%d", &x, &y, &w);
addedge(x, y, w);
} int s = ;
dfs(s, );
f[s] = d[s];
dp(s, );
int ans = ;
for(int i = ; i <= n; i++){
ans = max(ans, f[i]);
}
printf("%d\n", ans); }
return ;
}
poj3585 Accumulation Degree【树形DP】【最大流】的更多相关文章
-
$Poj3585\ Accumulation Degree$ 树形$DP/$二次扫描与换根法
Poj Description 有一个树形的水系,由n-1条河道与n个交叉点组成.每条河道有一个容量,联结x与y的河道容量记为c(x,y),河道的单位时间水量不能超过它的容量.有一个结点是整个水系的发 ...
-
poj3585 Accumulation Degree(树形dp,换根)
题意: 给你一棵n个顶点的树,有n-1条边,每一条边有一个容量z,表示x点到y点最多能通过z容量的水. 你可以任意选择一个点,然后从这个点倒水,然后水会经过一些边流到叶节点从而流出.问你最多你能倒多少 ...
-
poj3585 Accumulation Degree[树形DP换根]
思路其实非常简单,借用一下最大流求法即可...默认以1为根时,$f[x]$表示以$x$为根的子树最大流.转移的话分两种情况,一种由叶子转移,一种由正常孩子转移,判断一下即可.换根的时候由頂向下递推转移 ...
-
POJ3585:Accumulation Degree(换根树形dp)
Accumulation Degree Time Limit: 5000MS Memory Limit: 65536K Total Submissions: 3425 Accepted: 85 ...
-
POJ3585 Accumulation Degree 【树形dp】
题目链接 POJ3585 题解 -二次扫描与换根法- 对于这样一个无根树的树形dp 我们先任选一根进行一次树形dp 然后再扫一遍通过计算得出每个点为根时的答案 #include<iostream ...
-
题解 poj3585 Accumulation Degree (树形dp)(二次扫描和换根法)
写一篇题解,以纪念调了一个小时的经历(就是因为边的数组没有乘2 phhhh QAQ) 题目 题目大意:找一个点使得从这个点出发作为源点,流出的流量最大,输出这个最大的流量. 以这道题来介绍二次扫描和换 ...
-
AIM Tech Round 3 (Div. 1) (构造,树形dp,费用流,概率dp)
B. Recover the String 大意: 求构造01字符串使得子序列00,01,10,11的个数恰好为$a_{00},a_{01},a_{10},a_{11}$ 挺简单的构造, 注意到可以通 ...
-
POJ3585 Accumulation Degree【换根dp】
题目传送门 题意 给出一棵树,树上的边都有容量,在树上任意选一个点作为根,使得往外流(到叶节点,叶节点可以接受无限多的流量)的流量最大. 分析 首先,还是从1号点工具人开始$dfs$,可以求出$dp[ ...
-
poj3585 Accumulation Degree(换根dp)
传送门 换根dp板子题(板子型选手 题意: 一棵树确定源点和汇点找到最大的流量(拿出一整套最大瘤板子orz ; int head[maxn],tot; struct node { int nt,to; ...
随机推荐
-
AWS CloudFront CDN直接全站加速折腾记The request could not be satisfied. Bad request
ERROR The request could not be satisfied. Bad request. Generated by cloudfront (CloudFront) Request ...
-
SQL Server DB Type and CLR Type
这段时间学习SQL Server CLR编程,但是SQL CLR编程,里面所使用的数据类型为CLE TYPE,它多少与 Db TYPE有些区别,在网上找到一个列表http://geekswithblo ...
-
win7怎么显示隐藏文件夹
1. 点击“组织”,再选择“文件夹和搜索选项”命令. 2. 接下来在打开的“文件夹选项”对话框中,单击“查看”,切换到“查看”选项卡中. 3. 然后在下面的“高级设置”区域,取消“隐藏受保护的操作系统 ...
-
Javascript中字符串转换成Date的方法
//字符串转成Time(dateDiff)所需方法 function stringToTime(string) { var f = string.split(' ', 2); var d = (f[0 ...
-
Windows Phone开发之&rdquo;给我好评&ldquo;
课余时间搞了一年的Windows phone开发,最近又开始重拾C#编程之道,之前下载许多应用都有"给我好评"的界面,那个时候自己的应用都没有这个界面,于是到处百度谷歌,却 ...
-
Eclipse设置问题:字体大小、修改注释内容、修改快捷键
一.设置字体大小,看下图,包括了设计代码字体大小和控制台输出字体大小 二.修改注释内容 选择window---->>preferences 选择Java---->>code s ...
-
Photoshop 操作
本文主要记录在工作过程中使用ps的一些快捷键或操作顺序 1.ctrl+H:取消标尺 2.ctrl+D:取消选区 3.看矩形尺寸:选中矩形图层 >窗口 >属性(w:宽 H:高) 4.看图层 ...
-
Redis入门到高可用(十九)——Redis Sentinel
一.Redis Sentinel架构 二.redis sentinel安装与配置 四.客户端连接Sentinel 四.实现原理—— 故障转移演练(客户端高可用) 五.实 ...
-
学习测试框架Mocha
学习测试框架Mocha 注意:是参考阮老师的文章来学的.虽然阮老师有讲解,但是觉得自己敲一遍,然后记录一遍效果会更好点.俗话说,好记性不如烂笔头. Mocha 是javascript测试框架之一,可以 ...
-
Bootstrap @Media分类
手机的屏幕比较小,宽度通常在600像素以下:PC的屏幕宽度,一般都在1000像素以上(目前主流宽度是1366×768)设置相应的min-width和max-width值 所以响应式设计一般对600 ...