链接: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 }