HDU-4003 Find Metal Mineral 树形DP

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

  状态转移方程还是很好想的:f[i][j]表示第 i 个节点放 j 个机器人的最优解,f[i][j]=Min{ f[i][j] , f[i][j-k] + f[v][k] + (k?k:2)*e[i].w } 。

  写这个树形DP的时候,暴露了我以前没有仔细考虑的问题,导致状态转移的时候删删改改了很久。、

  1.仔细考虑转移方程初始化的问题,要根据求Min或者Max以及容量是否恰好来确定。

  2.在分组背包转移时,f[i][j]是前几组的最优值。

 1 //STATUS:C++_AC_256MS_1084KB
 2 #include<stdio.h>
 3 #include<stdlib.h>
 4 #include<string.h>
 5 #include<math.h>
 6 #include<iostream>
 7 #include<string>
 8 #include<algorithm>
 9 #include<vector>
10 #include<queue>
11 #include<stack>
12 #include<map>
13 using namespace std;
14 #define LL __int64
15 #define pii pair<int,int>
16 #define Max(a,b) ((a)>(b)?(a):(b))
17 #define Min(a,b) ((a)<(b)?(a):(b))
18 #define mem(a,b) memset(a,b,sizeof(a))
19 #define lson l,mid,rt<<1
20 #define rson mid+1,r,rt<<1|1
21 const int N=10010,INF=0x3f3f3f3f,MOD=10000,STA=8000010;
22 const double DNF=1e13;
23 
24 struct Node{
25     int u,v,w;
26 }e[N*2];
27 
28 int first[N],next[N*2],vis[N],f[N][11];
29 int n,s,k,mt;
30 
31 void adde(int a,int b,int c)
32 {
33     e[mt].u=a;e[mt].v=b;
34     e[mt].w=c;
35     next[mt]=first[a];first[a]=mt++;
36     e[mt].u=b;e[mt].v=a;
37     e[mt].w=c;
38     next[mt]=first[b];first[b]=mt++;
39 }
40 
41 void dfs(int u)
42 {
43     int i,j,v,q;
44     i=first[u];
45     vis[u]=1;
46     if((next[i]==-1 || i==-1) && u!=s){
47         f[u][0]=f[u][1]=0;
48         return;
49     }
50     f[u][0]=0;
51     for(;i!=-1;i=next[i]){
52         v=e[i].v;
53         if(vis[v])continue;
54         dfs(v); 
55         for(j=k;j>=1;j--){
56             f[u][j]+=f[v][0]+2*e[i].w;
57             for(q=1;q<=j;q++)
58                 f[u][j]=Min(f[u][j],f[u][j-q]+f[v][q]+q*e[i].w);
59         }
60         f[u][0]+=f[v][0]+2*e[i].w;
61     }
62 }
63 
64 int main()
65 {
66  //   freopen("in.txt","r",stdin);
67     int i,x,y,w;
68     while(~scanf("%d%d%d",&n,&s,&k))
69     {
70         mt=0;
71         mem(vis,0);
72         mem(f,0);
73         mem(first,-1);
74         for(i=1;i<n;i++){
75             scanf("%d%d%d",&x,&y,&w);
76             adde(x,y,w);
77         }
78 
79         dfs(s);
80 
81         printf("%d\n",f[s][k]);
82     }
83     return 0;
84 }

 

posted @ 2013-04-09 21:18  zhsl  阅读(400)  评论(0编辑  收藏  举报