博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
poj3585 Accumulation Degree【树形DP】【最大流】
阅读量:4332 次
发布时间:2019-06-06

本文共 4706 字,大约阅读时间需要 15 分钟。

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

151 2 111 4 133 4 54 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之后,流量的计算结果。

 

1 //#include 
2 #include
3 #include
4 #include
5 #include
6 #include
7 #include
8 #include
9 10 #define inf 0x3f3f3f3f 11 using namespace std; 12 typedef long long LL; 13 14 int n; 15 const int maxn = 2e5 + 5; 16 int head[maxn], cnt = 0, d[maxn], deg[maxn], f[maxn]; 17 struct edge{ 18 int x, y; 19 int nxt; 20 int c; 21 }edge[maxn * 2]; 22 23 void init() 24 { 25 memset(head, -1, sizeof(head)); 26 cnt = 0; 27 memset(d, 0, sizeof(d)); 28 memset(deg, 0, sizeof(deg)); 29 } 30 31 void addedge(int x, int y, int w) 32 { 33 edge[cnt].x = x; 34 edge[cnt].y = y; 35 edge[cnt].c = w; 36 edge[cnt].nxt = head[x]; 37 head[x] = cnt++; 38 edge[cnt].x = y; 39 edge[cnt].y = x; 40 edge[cnt].c = w; 41 edge[cnt].nxt = head[y]; 42 head[y] = cnt++; 43 deg[x]++; 44 deg[y]++; 45 } 46 47 void dfs(int rt, int fa) 48 { 49 int ans = 0; 50 for(int i = head[rt]; i != -1; i = edge[i].nxt){ 51 int y = edge[i].y; 52 if(y == fa){ 53 continue; 54 } 55 if(deg[y] == 1){ 56 ans += edge[i].c; 57 } 58 else{ 59 dfs(y, rt); 60 ans += min(d[y], edge[i].c); 61 } 62 } 63 d[rt] = ans; 64 return ; 65 } 66 67 void dp(int x, int fa) 68 { 69 for(int i = head[x]; i != -1; i = edge[i].nxt){ 70 int y = edge[i].y; 71 if(edge[i].y == fa)continue; 72 if(deg[x] == 1){ 73 f[y] = d[y] + edge[i].c; 74 } 75 else{ 76 f[y] = d[y] + min(f[x] - min(d[y], edge[i].c), edge[i].c); 77 } 78 dp(y, x); 79 } 80 } 81 82 int main() 83 { 84 int t; 85 scanf("%d", &t); 86 while(t--){ 87 init(); 88 scanf("%d", &n); 89 for(int i = 0; i < n - 1; i++){ 90 int x, y, w; 91 scanf("%d%d%d", &x, &y, &w); 92 addedge(x, y, w); 93 } 94 95 int s = 1; 96 dfs(s, 0); 97 f[s] = d[s]; 98 dp(s, 0); 99 int ans = 0;100 for(int i = 1; i <= n; i++){101 ans = max(ans, f[i]);102 }103 printf("%d\n", ans);104 105 }106 return 0;107 }

 

转载于:https://www.cnblogs.com/wyboooo/p/9762550.html

你可能感兴趣的文章
MySQL存储过程定时任务
查看>>
Python中and(逻辑与)计算法则
查看>>
POJ 3267 The Cow Lexicon(动态规划)
查看>>
设计原理+设计模式
查看>>
音视频处理
查看>>
tomcat 7服务器跨域问题解决
查看>>
前台实现ajax 需注意的地方
查看>>
Jenkins安装配置
查看>>
个人工作总结05(第二阶段)
查看>>
Java clone() 浅拷贝 深拷贝
查看>>
深入理解Java虚拟机&运行时数据区
查看>>
02-环境搭建
查看>>
spring第二冲刺阶段第七天
查看>>
搜索框键盘抬起事件2
查看>>
阿里百川SDK初始化失败 错误码是203
查看>>
透析Java本质-谁创建了对象,this是什么
查看>>
BFS和DFS的java实现
查看>>
关于jquery中prev()和next()的用法
查看>>
一、 kettle开发、上线常见问题以及防错规范步骤
查看>>
eclipse没有server选项
查看>>