In each case:
The first line specifies three integers N, S, K specifying the numbers of metal mineral, landing site and the number of robots.
The next n‐1 lines will give three integers x, y, w in each line specifying there is a path connected point x and y which should cost w.
1<=N<=10000, 1<=S<=N, 1<=k<=10, 1<=x, y<=N, 1<=w<=10000.
3 1 1 1 2 1 1 3 1 3 1 2 1 2 1 1 3 1
3 2HintIn the first case: 1->2->1->3 the cost is 3; In the second case: 1->2; 1->3 the cost is 2;
//
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
//K个机器人从S出发遍历树上所有点的经过的最小权值
const int maxn=11000;
const int inf=(1<<30);
struct Node
{
int t,w;
int next;
};
Node G[maxn*2];
int p[maxn];
int l;
void init()
{
memset(p,-1,sizeof(p));
l=0;
}
void addedge(int u,int t,int w)
{
G[l].w=w;
G[l].t=t;
G[l].next=p[u];
p[u]=l++;
}
//令 f[i][x] 为:有 x 个机器人从 i 号节点出发遍
//历以 i 为根的子树中的所有节点的最小代价。
//ans=max(f[s][j])1<=j<=k important j从1开始
int n,s,k;
int f[maxn][11];
void dfs(int u,int fath)
{
for(int l=p[u];l!=-1;l=G[l].next)
{
int t=G[l].t,w=G[l].w;
if(t==fath) continue;
dfs(t,u);//先计算子树
//计算f[u][i],这里f[u][i]表示的是u的前l个子树上的最小值
//这里从i k->0 利用了滚动数组的思想
for(int i=k;i>=0;i--)
{
int _min=inf;
//向t派j个去了不回来的机器人
for(int j=0;j<=i;j++)
{
//j=0 派一个去t,且回来u的机器人
int tmp=f[u][i-j]+f[t][j]+w*(j==0?2:j);
_min=min(_min,tmp);
}
f[u][i]=_min;
}
}
}
int main()
{
while(scanf("%d%d%d",&n,&s,&k)==3)
{
init();
for(int i=0;i<n-1;i++)
{
int u,t,w;scanf("%d%d%d",&u,&t,&w);
addedge(u,t,w);
addedge(t,u,w);
}
memset(f,0,sizeof(f));
dfs(s,-1);
int ans=inf;
for(int i=1;i<=k;i++) ans=min(ans,f[s][i]);
printf("%d\n",ans);
}
return 0;
}