標籤:
Apple Tree
| Time Limit: 1000MS |
|
Memory Limit: 65536K |
| Total Submissions: 7789 |
|
Accepted: 2606 |
Description
Wshxzt is a lovely girl. She likes apple very much. One day HX takes her to an apple tree. There are N nodes in the tree. Each node has an amount of apples. Wshxzt starts her happy trip at one node. She can eat up all the apples in the nodes she reaches. HX is a kind guy. He knows that eating too many can make the lovely girl become fat. So he doesn’t allow Wshxzt to go more than K steps in the tree. It costs one step when she goes from one node to another adjacent node. Wshxzt likes apple very much. So she wants to eat as many as she can. Can you tell how many apples she can eat in at most K steps.
Input
There are several test cases in the input
Each test case contains three parts.
The first part is two numbers N K, whose meanings we have talked about just now. We denote the nodes by 1 2 ... N. Since it is a tree, each node can reach any other in only one route. (1<=N<=100, 0<=K<=200)
The second part contains N integers (All integers are nonnegative and not bigger than 1000). The ith number is the amount of apples in Node i.
The third part contains N-1 line. There are two numbers A,B in each line, meaning that Node A and Node B are adjacent.
Input will be ended by the end of file.
Note: Wshxzt starts at Node 1.
Output
For each test case, output the maximal numbers of apples Wshxzt can eat at a line.
Sample Input
2 1 0 111 23 20 1 21 21 3
Sample Output
112
題目大意:給出一個n個節點的樹,每個節點上有個值,問不超過k步最高可以獲得的值。i到j算一步,j到i也算一步
輸入: 輸入n和k,然後是n個節點的值,然後是n-1個i j代表了i和j節點相鄰。根是1.
很容易看出來這是一個樹狀dp,dp[i][j]代表了以i節點為根,用j步可以得到的最大值,但是因為走到子樹算是一步,走回到根也是一步,所以就要有兩個dp關係,dp1[i][j]代表從i節點走j步又回到j節點的最大值,dp2[i][j]代表從i節點走j步不會到i節點的最大值。
那麼狀態轉移方程為:當前節點為u,子樹為v
回到i節點時:在節點u走j步,在子樹v中走k步,從u到v和從v到u共走兩步,那麼在除v之外的其他子樹走了j-k-2步。
dp1[u][j] = max(dp1[u][j],dp1[u][j-k-2]+dp1[v][k])
不回到i節點時:從節點u走j步
1.不在v子樹中返回u,那麼會在其他子樹中返回u,在v中走k步,在u到v走一步,在除v外的子樹走j-k-1步。
dp2[u][j] = max(dp2[u][j],dp1[u][j-k-1]+dp2[v][k])
2.在v子樹中返回u,那麼會在其他子樹中存在不返回u的,在v中走k步,在u到v和v到u走兩步,在除v之外的子樹走j-k-2步。
dp2[u][j] = max(dp2[u][j],dp2[u][j-k-2]+dp1[v][k])
注意1:輸入的節點i,j是相鄰的關係,根是1。
#include <cstdio>#include <cstring>#include <algorithm>#include <queue>using namespace std ;struct tree{ int v , next ;}edge[110];int head[110] , cnt ;int dp1[110][210] , dp2[110][210] ;//dp1返回,dp2不返回 dp[i][j]:從i節點出發使用j步可以得到的最大值int c[110] , n , m ;void add(int u,int v) { edge[cnt].v = v ; edge[cnt].next = head[u] ; head[u] = cnt++ ; return ;}void dfs(int u) { int i , j , k , v ; dp1[u][0] = dp2[u][0] = c[u] ; if( head[u] == -1 ) return ; for(i = head[u] ; i != -1 ; i = edge[i].next) { v = edge[i].v ; dfs(v) ; } for(i = head[u] ; i != -1 ; i = edge[i].next) { v = edge[i].v ; for(j = m ; j >= 0 ; j--) { for(k = 0 ; k <= j ; k++) { if( k+2 <= j ) { dp1[u][j] = max(dp1[u][j],dp1[u][j-k-2]+dp1[v][k]) ; dp2[u][j] = max(dp2[u][j],dp2[u][j-k-2]+dp1[v][k]) ; } if( k+1 <= j ) dp2[u][j] = max(dp2[u][j],dp1[u][j-k-1]+dp2[v][k]) ; } } }}int Map[110][110] ;queue <int> que ;void bfs(int n) { while( !que.empty() ) que.pop() ; que.push(1) ; int i , u , v ; while( !que.empty() ) { u = que.front() ; que.pop() ; for(i = 1 ; i <= n ; i++){ if( Map[u][i] == 1 ) { Map[u][i] = Map[i][u] = 0 ; add(u,i) ; que.push(i) ; } } }}int main() { int i , j , u , v ; while( scanf("%d %d", &n, &m) != EOF ) { memset(head,-1,sizeof(head)) ; memset(dp1,0,sizeof(dp1)) ; memset(dp2,0,sizeof(dp2)) ; memset(Map,0,sizeof(Map)) ; cnt = 0 ; for(i = 1 ; i <= n ; i++) scanf("%d", &c[i]) ; for(i = 1 ; i < n ; i++) { scanf("%d %d", &u, &v) ; Map[u][v] = Map[v][u] = 1 ; } bfs(n) ; dfs(1) ; int max1 = 0 ; for(i = 0 ; i <= m ; i++) { max1 = max(max1,dp2[1][i]) ; } printf("%d\n", max1) ; } return 0 ;}
poj2486--Apple Tree(樹狀dp)