【POJ3585】Accumulation Degree

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/m0_38083668/article/details/82796030

                                               Accumulation Degree

Time Limit: 5000MS   Memory Limit: 65536K
Total Submissions: 3031   Accepted: 750

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

解析:
       树形DP。

       令d[i]为以i为根的子树的最大流量,f[i]为以i为整棵树的根的最大流量,如果以每个点位根都DFS一遍复杂度是O(N^2)肯定会超时,这里有一种比较常用的方法:二次扫描+换根法。

       首先一遍DFS容易算出以1为根的最优解,然后再DFS一遍算出以每个点为根的最优解,于是就有状态转移方程:

       f[to]=d[to]+\begin{Bmatrix} min(f[from]-min(d[to],c(x,y)),c(x,y))(du(x)==1)\\ c(x,y)(du(x)!=1) \end{Bmatrix}

代码:

#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
using namespace std;

const int Max=200005;
int t,n,m,size,ans;
int first[Max],d[Max],f[Max],du[Max];
struct shu{int to,next,len;};
shu edge[Max<<1];

inline int get_int()
{
	int x=0,f=1;
	char c;
	for(c=getchar();(!isdigit(c))&&(c!='-');c=getchar());
	if(c=='-') f=-1,c=getchar();
	for(;isdigit(c);c=getchar()) x=(x<<3)+(x<<1)+c-'0';
	return x*f;
}

inline void pre()
{
	size=ans=0;
	for(int i=1;i<=n;i++) first[i]=d[i]=f[i]=du[i]=0;
}

inline void build(int x,int y,int z)
{
	edge[++size].next=first[x];
	first[x]=size;
	edge[size].to=y,edge[size].len=z;
}

inline void dfs1(int point,int fa)
{
	for(int u=first[point];u;u=edge[u].next)
	{
	  int to=edge[u].to;
	  if(to==fa) continue;
	  dfs1(to,point);
	  if(du[to]==1) d[point]+=edge[u].len;
	  else d[point]+=min(d[to],edge[u].len);
	}
}

inline void dfs2(int point,int fa)
{
	for(int u=first[point];u;u=edge[u].next)
	{
	  int to=edge[u].to;
	  if(to==fa) continue;
	  if(du[point]==1) f[to]=d[to]+edge[u].len;
	  else f[to]=d[to]+min(edge[u].len,f[point]-min(d[to],edge[u].len));
	  dfs2(to,point);
	}
}

int main()
{
	t=get_int();
	while(t--)
	{
	  pre();
	  n=get_int();
	  for(int i=1;i<n;i++)
	  {
	 	int x=get_int(),y=get_int(),z=get_int();
	 	build(x,y,z),build(y,x,z),du[x]++,du[y]++;
	  }
	  dfs1(1,0);
	  f[1]=d[1];
	  dfs2(1,0);
	  for(int i=1;i<=n;i++) ans=max(ans,f[i]);
	  cout<<ans<<"\n";
	}
	return 0;
}

猜你喜欢

转载自blog.csdn.net/m0_38083668/article/details/82796030
今日推荐