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. Ubuntu环境下使用npm安装node模块时报错的处理方法

    错误信息: npm ERR : node: not found : npm ERR! not ok code 0 解决方案: sudo apt-get install nodejs-legacy 也可 ...

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

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

  3. 折腾kali linux2.0

    偶然的机会了解到了kali linux这个用于渗透测试的linux发行版,于是就从官网下了iso,但是制作启动盘老出错.网上查了下说在linux下用dd命令特别简单,于是转到ubuntu下制作启动盘, ...

  4. spoj687(后缀数组)

    http://www.spoj.com/problems/REPEATS/ 题意:给一串字符,需要你求这一串字符中有连续重复的字符的重复次数....... 思路:这是和poj3693一种类型的题目.. ...

  5. 读取大csv文件数据插入到MySql或者Oracle数据库通用处理

    import java.io.BufferedInputStream; import java.io.BufferedReader;import java.io.BufferedWriter;impo ...

  6. [usb]usb otg和host

    USB OTG 设备既能做主机,又能做设备.USB HOST是指主机.当OTG 插到 HOST 上,OTG 的角色 就是 device.当device 插到 OTG 上,OTG 的角色就是 HOST. ...

  7. PHP——分页显示数据库内容

    test.php <?php header("Content-Type:text/html;charset=utf-8"); //加载分页类 include "pa ...

  8. Android基础总结(七)BroadcastReceiver

    广播(掌握) 广播的概念 现实:电台通过发送广播发布消息,买个收音机,就能收听 Android:系统在产生某个事件时发送广播,应用程序使用广播接收者接收这个广播,就知道系统产生了什么事件. Andro ...

  9. 使用导出导入(datapump)方式将普通表切换为分区表

    随着数据库数据量的不断增长,有些表须要由普通的堆表转换为分区表的模式. 有几种不同的方法来对此进行操作,诸如导出表数据,然后创建分区表再导入数据到分区表:使用EXCHANGE PARTITION方式来 ...

  10. Golang HTTP文件上传

    2018年02月08日 10:07:13 冷月醉雪 阅读数:346 标签: golangHTTP文件上传更多 个人分类: Go   版权声明:本文为博主原创文章,未经博主允许不得转载. https:/ ...