Accumulation Degree
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:

  1. Each edge of the tree has an positive capacity.
  2. The nodes with degree of one in the tree are named terminals.
  3. The flow of each edge can't exceed its capacity.
  4. 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 xyz 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】【最大流】的更多相关文章

  1. $Poj3585\ Accumulation Degree$ 树形$DP/$二次扫描与换根法

    Poj Description 有一个树形的水系,由n-1条河道与n个交叉点组成.每条河道有一个容量,联结x与y的河道容量记为c(x,y),河道的单位时间水量不能超过它的容量.有一个结点是整个水系的发 ...

  2. poj3585 Accumulation Degree(树形dp,换根)

    题意: 给你一棵n个顶点的树,有n-1条边,每一条边有一个容量z,表示x点到y点最多能通过z容量的水. 你可以任意选择一个点,然后从这个点倒水,然后水会经过一些边流到叶节点从而流出.问你最多你能倒多少 ...

  3. poj3585 Accumulation Degree[树形DP换根]

    思路其实非常简单,借用一下最大流求法即可...默认以1为根时,$f[x]$表示以$x$为根的子树最大流.转移的话分两种情况,一种由叶子转移,一种由正常孩子转移,判断一下即可.换根的时候由頂向下递推转移 ...

  4. POJ3585:Accumulation Degree(换根树形dp)

    Accumulation Degree Time Limit: 5000MS   Memory Limit: 65536K Total Submissions: 3425   Accepted: 85 ...

  5. POJ3585 Accumulation Degree 【树形dp】

    题目链接 POJ3585 题解 -二次扫描与换根法- 对于这样一个无根树的树形dp 我们先任选一根进行一次树形dp 然后再扫一遍通过计算得出每个点为根时的答案 #include<iostream ...

  6. 题解 poj3585 Accumulation Degree (树形dp)(二次扫描和换根法)

    写一篇题解,以纪念调了一个小时的经历(就是因为边的数组没有乘2 phhhh QAQ) 题目 题目大意:找一个点使得从这个点出发作为源点,流出的流量最大,输出这个最大的流量. 以这道题来介绍二次扫描和换 ...

  7. POJ3585 Accumulation Degree (树形DP-二次扫描与换根)

    本题属于不定根的树形DP,若以每个节点为根求解一次,复杂度太高,所以可以用换根的技巧. d[u]表示以u为根向下可以流的最大流量,这个是比较好求的,直接遍历到叶子节点,由子节点信息更新父节点.然后进行 ...

  8. 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}$ 挺简单的构造, 注意到可以通 ...

  9. POJ3585 Accumulation Degree【换根dp】

    题目传送门 题意 给出一棵树,树上的边都有容量,在树上任意选一个点作为根,使得往外流(到叶节点,叶节点可以接受无限多的流量)的流量最大. 分析 首先,还是从1号点工具人开始$dfs$,可以求出$dp[ ...

随机推荐

  1. atitit.自己动手开发编译器and解释器(2) ------语法分析,语义分析,代码生成--attilax总结

    atitit.自己动手开发编译器and解释器(2) ------语法分析,语义分析,代码生成--attilax总结 1. 建立AST 抽象语法树 Abstract Syntax Tree,AST) 1 ...

  2. docker容器跑tomcat遇到的坑

    使用docker容器跑tomcat,由于同一个宿主机上跑了多个容器,再加上宿主机本身跑了很多进程,导致系统总的进程数达到了8000+,而容器中tomcat的启动脚本中会调用自带的setenv.sh,在 ...

  3. Torch实现ReQU,和梯度验证

    重写函数 我们使用torch实现我们自己的ReQU模块.在实现一个新的layer之前,我们必须了解,我们并不是重写forward和backward方法,而是重写里面调用的其它方法. 1)又一次upda ...

  4. Phonegap创建项目语法

    1:在本地磁盘新建一个文件夹存放要开发的项目,比如在D盘建一个yun文件夹2 2:然后在dos系统下,d:命令进入d盘,cd yun进入yun文件夹, 3:然后phonegap create yun2 ...

  5. java线程阻塞问题排查方法

    我开发的worker,每隔几个月线上都会阻塞一次,一直都没查出问题.今天终于了了这个心结.把解决过程总结下和大家分享. 首先用jstack命令打出这个进程的全部线程堆栈.拿到线程dump文件之后,搜索 ...

  6. ORACLE中DELETE和TRUNCATE的区别

    语法 delete from AA truncate table AA 区别 1.delete from后面可以写条件(也就是where子句,delete from AA where aa.列名 = ...

  7. java 代理模式,观察者模式

    代理模式1 import <a href="http://lib.csdn.net/base/17" class='replace_word' title="Jav ...

  8. Ubuntu 11.04 下安装配置 JDK 7

    第一步:下载jdk-7-linux-i586.tar.gz wget -c http://download.oracle.com/otn-pub/java/jdk/7/jdk-7-linux-i586 ...

  9. PHP——动态随机数

    取1-13随机数 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://ww ...

  10. 深入理解JVM--JVM垃圾回收机制(转)

    Java语言出来之前,大家都在拼命的写C或者C++的程序,而此时存在一个很大的矛盾,C++等语言创建对象要不断的去开辟空间,不用的时候有需要不断的去释放控件,既要写构造函数,又要写析构函数,很多时候都 ...