1. 程式人生 > >Find Metal Mineral HDU

Find Metal Mineral HDU

  • 題意: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;
    }