题目描述
有一棵苹果树,如果树枝有分叉,一定是分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
二……二叉树……
二叉树大概只要DFS就可以了呀……写完树规才反应过来。
1 /*by SilverN*/ 2 #include3 #include 4 #include 5 #include 6 #include 7 #include 8 using namespace std; 9 const int mxn=210;10 int read(){11 int x=0,f=1;char ch=getchar();12 while(ch<'0' || ch>'9'){ if(ch=='-')f=-1;ch=getchar();}13 while(ch>='0' && ch<='9'){x=x*10+ch-'0';ch=getchar();}14 return x*f;15 }16 struct edge{17 int v,nxt;18 int dis;19 }e[mxn];20 int hd[mxn],mct=0;21 void add_edge(int u,int v,int dis){22 e[++mct].v=v;e[mct].nxt=hd[u];e[mct].dis=dis;hd[u]=mct;23 return;24 }25 int n,q;26 int f[mxn][mxn];27 int num[mxn];28 int w[mxn];29 void DP(int u,int fa){30 for(int i=1;i<=num[u];i++){31 f[u][i]=w[u];32 }33 for(int i=hd[u];i;i=e[i].nxt){34 int v=e[i].v;35 if(v==fa)continue;36 DP(v,u);37 for(int j=num[u];j;j--){38 for(int k=min(num[v],j-1);k>=0;k--){39 f[u][j]=max(f[u][j],f[u][j-k]+f[v][k]);40 }41 }42 }43 return;44 }45 void Build(int u,int fa){46 num[u]++;47 for(int i=hd[u];i;i=e[i].nxt){48 int v=e[i].v;49 if(v==fa)continue;50 w[v]=e[i].dis;51 Build(v,u);52 num[u]+=num[v];53 }54 return;55 }56 int main(){57 int i,j;58 n=read();q=read();59 int u,v,d;60 for(i=1;i