hdu5834Magic boy Bi Luo with his excited tree(树形DP)

Magic boy Bi Luo with his excited tree

Time Limit: 8000/4000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others)
Total Submission(s): 823    Accepted Submission(s): 222


Problem Description
Bi Luo is a magic boy, he also has a migic tree, the tree has  N nodes , in each node , there is a treasure, it's value is  V[i], and for each edge, there is a cost  C[i], which means every time you pass the edge  i , you need to pay  C[i].

You may attention that every  V[i] can be taken only once, but for some  C[i] , you may cost severial times.

Now, Bi Luo define  ans[i] as the most value can Bi Luo gets if Bi Luo starts at node  i.

Bi Luo is also an excited boy, now he wants to know every  ans[i], can you help him?
 

Input
First line is a positive integer  T(T104) , represents there are  T test cases.

Four each test:

The first line contain an integer  N (N105).

The next line contains  N integers  V[i], which means the treasure’s value of node  i(1V[i]104).

For the next  N1 lines, each contains three integers  u,v,c , which means node  u and node  v are connected by an edge, it's cost is  c(1c104).

You can assume that the sum of  N will not exceed  106.
 

Output
For the i-th test case , first output Case #i: in a single line , then output  N lines , for the i-th line , output  ans[i] in a single line.
 

Sample Input
 
   
1 5 4 1 7 7 7 1 2 6 1 3 1 2 4 8 3 5 2
 

Sample Output
 
   
Case #1: 15 10 14 9 15
 
这道题的题意就是给你一个树,每一个节点有一个收益,每条边每次经过都会有一个花费。问你从每个节点出发,最大的收益是多少。
这道题就是一个很明显的树形DP了,两个dfs,一个dfs是更新每个节点从当前节点出发回到原点的最大收益和不回到原点的最大收益,以及到达的位置。
第二个dfs是从父节点向下更新每个节点的答案。这个还是不难想的,就是细节有点多写起来有些烦。
AC代码:
#include
#include
#include
#include
using namespace std;
const int maxn=1e5+5;
int head[maxn],tot,val[maxn];
int w[maxn],bw[maxn],wid[maxn],ans[maxn];
/*
	w表示当前回来的最大收益 
	bw表示当前走出去的最大收益 
	id表示做出去的最大收益的节点 
*/
void init(){
	memset(head,-1,sizeof(head));
	tot=0;
}
struct Edge{
	int from,to,next,cost;
	Edge(){}
	Edge(int from,int to,int cost,int next){
		this->from=from;
		this->to=to;
		this->cost=cost;
		this->next=next;
	}
}e[maxn*2];
void add_edge(int u,int v,int c){
	e[tot]=Edge(u,v,c,head[u]);
	head[u]=tot++;
	e[tot]=Edge(v,u,c,head[v]);
	head[v]=tot++;
}
void dfs1(int u,int fa){
	w[u]=val[u];
	bw[u]=val[u];
	wid[u]=0;
	for(int i=head[u];~i;i=e[i].next){
		int v=e[i].to;
		if(v==fa)	continue;
		dfs1(v,u);
		int btemp=max(0,bw[v]-e[i].cost*2);//回来的收益 
		int temp=bw[u]+max(0,w[v]-e[i].cost);//不回来的收益 
		w[u]+=btemp;
		bw[u]+=btemp;
		if(w[u]





你可能感兴趣的:(树状DP)