HDOJ 4003Find Metal Mineral解题报告

链接:http://acm.hdu.edu.cn/showproblem.php?pid=4003

11年大连赛区预选赛的一道树形DP题,DP[i][j]表示以i为根节点的子树派j个机器人遍历整棵子树所走过的最短的总路径,dp[i][0]表示遍历完之后又回到i节点的值

View Code
 1 #include<iostream>
 2 #include<cstring>
 3 #include<cstdio>
 4 #define N 10005
 5 #define K 15
 6 using namespace std;
 7 int head[N],cnt;
 8 struct node
 9 {
10     int v,w,next;
11 };
12 node e[2*N];
13 int dp[N][15];
14 int n,s,r;
15 int min(int a,int b)
16 {
17     return a<b?a:b;
18 }
19 void add(int u,int v,int w)
20 {
21     e[cnt].v=v;
22     e[cnt].w=w;
23     e[cnt].next=head[u];
24     head[u]=cnt++;
25     e[cnt].v=u;
26     e[cnt].w=w;
27     e[cnt].next=head[v];
28     head[v]=cnt++;
29 }
30 void init()
31 {
32     memset(head,-1,sizeof(head));
33     memset(dp,0,sizeof(dp));
34     cnt=0;
35 }
36 void dfs(int u,int fa)
37 {
38     int i,j,k,w,v;
39     for(i=head[u];i>=0;i=e[i].next)
40     {
41         v=e[i].v;
42         w=e[i].w;
43         if(v==fa)
44         continue;
45         dfs(v,u);
46         for(j=r;j>=0;j--)
47         {
48             dp[u][j]+=dp[v][0]+2*w;
49             for(k=1;k<=j;k++)
50             dp[u][j]=min(dp[u][j],dp[u][j-k]+dp[v][k]+k*w);
51         }
52     }
53 }
54 int main()
55 {
56     int i,j,u,v,w;
57     while(scanf("%d%d%d",&n,&s,&r)!=EOF)
58     {
59         init();
60         for(i=1;i<=n-1;i++)
61         {
62             scanf("%d%d%d",&u,&v,&w);
63             add(u,v,w);
64         }
65         dfs(s,-1);
66         printf("%d\n",dp[s][r]);
67     }
68     return 0;
69 }
原文地址:https://www.cnblogs.com/caozhenhai/p/2669162.html