標籤:read 樹根 head 描述 continue ble def main 需要
https://www.luogu.org/problem/show?pid=2015題目描述
有一棵蘋果樹,如果樹枝有分叉,一定是分2叉(就是說沒有只有1個兒子的結點)
這棵樹共有N個結點(葉子點或者樹枝分叉點),編號為1-N,樹根編號一定是1。
我們用一根樹枝兩端串連的結點的編號來描述一根樹枝的位置。下面是一顆有4個樹枝的樹
2 5 \ / 3 4 \ / 1 現在這顆樹枝條太多了,需要剪枝。但是一些樹枝上長有蘋果。
給定需要保留的樹枝數量,求出最多能留住多少蘋果。
輸入輸出格式
輸入格式:
第1行2個數,N和Q(1<=Q<= N,1<N<=100)。
N表示樹的結點數,Q表示要保留的樹枝數量。接下來N-1行描述樹枝的資訊。
每行3個整數,前兩個是它串連的結點的編號。第3個數是這根樹枝上蘋果的數量。
每根樹枝上的蘋果不超過30000個。
輸出格式:
一個數,最多能留住的蘋果的數量。
輸入輸出範例輸入範例#1:
5 21 3 11 4 102 3 203 5 20
輸出範例#1:
21
f[i][j]表示節點i保留j個枝條能得到的最多蘋果數
1 #include <cstdio> 2 3 inline void read(int &x) 4 { 5 x=0; register char ch=getchar(); 6 for(; ch>‘9‘||ch<‘0‘; ) ch=getchar(); 7 for(; ch>=‘0‘&&ch<=‘9‘; ch=getchar()) x=x*10+ch-‘0‘; 8 } 9 const int N(105);10 int head[N],sumedge;11 struct Edge {12 int v,w,next;13 Edge(int v=0,int next=0,int w=0):14 v(v),next(next),w(w){}15 }edge[N<<1];16 inline void ins(int u,int v,int w)17 {18 edge[++sumedge]=Edge(v,head[u],w);19 head[u]=sumedge;20 edge[++sumedge]=Edge(u,head[v],w);21 head[v]=sumedge;22 }23 24 #define min(a,b) (a<b?a:b)25 #define max(a,b) (a>b?a:b)26 27 int n,q,f[N][N];28 int DFS(int u,int fa)29 {30 int sum=0;31 for(int v,i=head[u]; i; i=edge[i].next)32 {33 v=edge[i].v;34 if(v==fa) continue;35 sum+=DFS(v,u)+1;36 for(int j=min(sum,q); j; --j)37 for(int k=0; k<j; ++k)38 f[u][j]=max(f[u][j],f[u][j-k-1]+f[v][k]+edge[i].w);39 }40 return sum;41 }42 43 int Presist()44 {45 read(n),read(q);46 for(int u,v,w,i=1; i<n; ++i)47 read(u),read(v),read(w),ins(u,v,w);48 DFS(1,0);49 printf("%d\n",f[1][q]);50 return 0;51 }52 53 int Aptal=Presist();54 int main(){;}
洛穀—— P2015 二叉蘋果樹