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. Linux 硬链接和软链接

    硬链接:ln 源文件 新建名 指向同一个文件,并独立存在.当源文件删除不会影响硬链接文件的读取.不能跨文件系统和目录建连接. 例:新建一个文件吧!名字test 硬链接为t1. 查看文件,发现2个文件最 ...

  2. 在ubuntu下安装sourceinsight

    执行更新与安装 wine: # sudo apt-get update # sudo apt-get install wine 下载SourceInsight,用wine来安装: 执行:wine so ...

  3. awk 计算数据的和和平均值

    awk 计算数据的和和平均值 2014年12月02日 21:11:12 HaveFunInLinux 阅读数:14487更多 个人分类: 小技巧   本文译至:http://d.hatena.ne.j ...

  4. CI 多表关联查询

    方法一:$this->db->query("sql  语句");     直接写sql语句 方法二: #多表关联查询 $data=$this->db->fr ...

  5. 关于Nvelocity的主要语法和一些代码示例

    context.Response.ContentType = "text/html"; VelocityEngine vltEngine = new VelocityEngine( ...

  6. CLion 2017 注册码

    注册码使用时间2017-2018 CNEKJPQZEX-eyJsaWNlbnNlSWQiOiJDTkVLSlBRWkVYIiwibGljZW5zZWVOYW1lIjoibGFuIHl1IiwiYXNz ...

  7. 通过公网IP主机建立ssh隧道

    环境描述 hostA: 有公网IP的linux主机 hostB: 私有路由器后端无公网IPlinux主机,能够ssh连接到hostA hostC: 个人pc机 隧道创建步骤 step1 在hostB上 ...

  8. thinkphp中phpexcel的使用

    1.下载phpexcel文件(之前提到过!) 2.下载后将文件放到: 3.在控制器中引用: 4.部分实现的代码: public function OutputExcel($data) //导入订单 { ...

  9. Python使用pycurl获取http的响应时间

    最近需要对节点到源站自己做个监控,简单的ping可以检测到一些东西,但是http请求的检查也要进行,于是就研究了下pycurlpycurl是个用c语言实现的python 库,虽然据说不是那么pytho ...

  10. WebApi(6) 后台C#调用WebApi

    https://www.cnblogs.com/cxd1008/p/6640015.html 今天来写一下后台C#代码如何访问webapi 这里使用HttpClient方法访问webapi也是很常用的 ...