//k个机器人从一颗树的树根开始往下走,
//走树的每条边都要消耗能量,问这k个人最少花多少能量能遍历所有点
//dp[u][i] 表示以u点为根节点的子树用i个节点遍历最少需要多少能量
//当i = 0时表示有一个点遍历了这颗子树又返回上一个节点
#include<cstdio>
#include<cstring>
#include<iostream>
#include<vector>
using namespace std ;
const int maxn = 10010 ;
const int inf = 0x3f3f3f3f;
int dp[maxn][60] ;
int head[maxn] ;
int nedge ;
int n , s , m;
struct Edge
{
int v , w ;
int next ;
}edge[maxn<<1] ;
void addedge(int u , int v , int w)
{
edge[nedge].v = v ;
edge[nedge].w = w;
edge[nedge].next = head[u] ;
head[u] = nedge++;
}
void dfs(int u , int pre)
{
int flag = 0 ;
for(int i = head[u] ;i != -1 ;i =edge[i].next)
{
int v = edge[i].v ;
if(v == pre)continue ;
dfs(v , u) ;
int len = edge[i].w ;
for(int j = m;j >= 0;j--)
{
int sum = inf ;
for(int k = 0;k <= j;k++)
{
int tmp = (k == 0 ? 2*len : k*len);
sum = min(sum , dp[u][j-k] + dp[v][k] + tmp) ;
}
dp[u][j] = sum;
}
}
}
int main()
{
//freopen("in.txt" ,"r" , stdin) ;
while(~scanf("%d%d%d" ,&n , &s , &m))
{
memset(head , -1 , sizeof(head)) ;
memset(dp , 0 ,sizeof(dp)) ;
nedge = 0 ;
for(int i = 1;i < n;i++)
{
int u , v , w ;
scanf("%d%d%d" , &u , &v , &w) ;
addedge(u , v , w) ;
addedge(v , u , w) ;
}
dfs(s,0) ;
cout<<dp[s][m]<<endl;
}
return 0 ;
}
版权声明:本文为博主原创文章,未经博主允许不得转载。
时间: 2024-11-08 20:04:31