Find Metal Mineral HDU
阿新 • • 發佈:2018-12-18
- 題意:k個機器人到S點,問機器人找完所有金礦後,最短的移動距離;如果只有一個機器人,
- 他就要找遍所有金礦就會走重複的路,直到找到最後一個礦;如果有兩個機器人,他倆就可以分頭行動;
- 思路:dp[i][j]=min(dp[i][j-k]+dp[son][k] | 0<=k<=j)設dp[i][j]表示i節點分配j個機器人的最短移動距離
- 0並不表示不分配機器人了,而是隻有一個機器人分配過來,並且最終返回父節點;
-
#include<bits/stdc++.h> using namespace std; #define inf 0x3f3f3f3f #define maxn 10086 int n,k,s,x,y,z; int head[maxn],tot; int dp[maxn][15]; struct node { int v,w,to; } edge[maxn*2]; void add(int x,int y,int z) { edge[++tot].v=y; edge[tot].w=z; edge[tot].to=head[x]; head[x]=tot; edge[++tot].v=x; edge[tot].w=z; edge[tot].to=head[y]; head[y]=tot; } void dfs(int root,int pre) { for(int i=head[root]; i!=-1; i=edge[i].to) { int son=edge[i].v; int dis=edge[i].w; if(son==pre)continue; dfs(son,root); for(int j=k; j>=0; j--) { dp[root][j]+=dp[son][0]+dis*2; for(int p=1; p<=j; p++) dp[root][j]=min(dp[root][j],dp[root][j-p]+dp[son][p]+dis*p); } } } int main() { while(~scanf("%d%d%d",&n,&s,&k)) { tot=0; memset(head,-1,sizeof(head)); memset(dp,0,sizeof(dp)); for(int i=1; i<n; i++) { scanf("%d%d%d",&x,&y,&z); add(x,y,z); } dfs(s,s); printf("%d\n",dp[s][k]); } return 0; }