1. 程式人生 > >Teemo's tree problem

Teemo's tree problem

hid play eem spl ++ inf 根節點 != rst

題目鏈接 : https://nanti.jisuanke.com/t/29228

There is an apple tree in Teemo‘s yard. It contains n nodes and n-1 branches, and the node 1 is always the root of the tree. Today, Teemo‘s father will go out for work. So Teemo should do his father‘s job in the family: Cut some branches to make the tree more beautiful. His father‘s told him that he should cut some branches, finally, the tree should just contains q branches. But when Teemo start to cut, he realizes that there are some apples in the branches( For example, there are 10 apples in the branches which connecting node 1 and node 4). So Teemo not only wants to achieve his father‘s order, but also wants to preserve apples as much as possible. Can you help him?

2 5
\ /
3 4
\ /
1

Input Format

The first line of the input contains an integer T(1<=T<=10) which means the number of test cases.

For each test case, The first line of the input contains two integers n,q(3<=n<=100,1<=q<=n-1), giving the number of the node and the number of branches that the tree should preserve.
In the next n-1 line, each line contains three integers u,v,w(1<=u<=n,1<=v<=n,u!=v,1<=w<=100000), which means there is a branch connecting node u and node v, and there are w apple(s) on it.

Output Format

Print a single integer, which means the maximum possible number of apples can be preserved.
樣例輸入

1
5 2
1 3 1
1 4 10
2 3 20
3 5 20

樣例輸出

21


題意是有一棵以 1號點為根節點的 n個結點的樹, n-1 條邊均有權值,現在把這棵樹在保留根節點的情況下剪成一棵 q條邊的樹並且使剩余的樹權值最大。(註意 : 減去一條邊該邊後面的邊都會被去掉)

這應該是一道十分經典的樹形dp 。

除根節點外將 邊的權值賦給點,val[i]記錄i號點的權值。

have[i] 表示i號點及其之後的所有點的個數, dp[i][j]表示在i號點為"根"的情況下共保留j個點的最大權值。

做題時想到了邊值賦點,卻不知如何dp,樹形dp還是見少了。

技術分享圖片
 1 #include<bits/stdc++.h>
 2 using namespace std;
 3
#define pb(x) push_back((x)) 4 5 typedef long long ll; 6 const int INF=0x3f3f3f3f; 7 struct Edge{ 8 int to; 9 int wei; 10 Edge(int v,int w):to(v),wei(w) {} 11 }; 12 vector< Edge > G[101]; 13 int val[101]; 14 int have[101]; 15 int dp[101][101]; 16 17 void getVal(int u){ 18 for
( auto e : G[u]){ 19 if(val[e.to]==0){ 20 val[e.to]=e.wei; 21 getVal(e.to); 22 } 23 } 24 } 25 26 int dfs(int u,int fa){ 27 have[u]=1; 28 for( auto e : G[u]){ 29 if(e.to==fa) continue; 30 have[u]+=dfs(e.to,u); 31 } 32 dp[u][1]=val[u]; 33 for( auto e : G[u]){ 34 if(e.to==fa) continue; 35 for(int tot=have[u];tot>=1;tot--){ 36 for(int i=1;i<tot&&i<=have[e.to];++i){ 37 dp[u][tot]=max(dp[u][tot],dp[u][tot-i]+dp[e.to][i]); 38 } 39 } 40 } 41 return have[u]; 42 } 43 44 int main(){ 45 int T; 46 scanf("%d",&T); 47 while(T--){ 48 int N,rmn; 49 scanf("%d%d",&N,&rmn); 50 for(int i=1;i<=N;++i) G[i].clear(); 51 for(int i=0;i<N-1;++i){ 52 int u,v,w; 53 scanf("%d%d%d",&u,&v,&w); 54 G[u].pb(Edge(v,w)); 55 G[v].pb(Edge(u,w)); 56 } 57 memset(val,0,sizeof(val)); 58 memset(have,0,sizeof(have)); 59 memset(dp,0,sizeof(dp)); 60 val[1]=INF; 61 getVal(1); 62 /* 63 for(int i=1;i<=N;++i) 64 printf("%d : %d\n",i,val[i]); 65 */ 66 val[1]=0; 67 dfs(1,0); 68 int ans=dp[1][rmn+1]; 69 printf("%d\n",ans); 70 } 71 return 0; 72 }
View Code

Teemo's tree problem