标签:des style http color java os io strong
题意:
一棵有权树,从根结点中放入 K 个机器人,求用这 K 个机器人遍历所有的结点最少的权值和。
思路:
1. dp[u][i] 表示给以 u 为根节点的子树放 i 个机器人,遍历其子树所需要的最小权值。
2. 关键在于 dp[u][0] 的理解,表示:最后停留在以 u 为根节点的子树下 0 个机器人,并且遍历了 u 子树的最小权值和。
3. 下面的步骤就变成和分组背包类似的情况了,根节点 u 给孩子 v 放多少个机器人。
4. dp[u][i] = min(dp[u][i], dp[u][j] + dp[v][i-j] + (i-j) * c); 可以理解成给 v 放了 i-j 个机器人,给 v 的其他兄弟放了 j 个,u 总共有 i 个
3 1 1 1 2 1 1 3 1 3 1 2 1 2 1 1 3 1
3 2HintIn the first case: 1->2->1->3 the cost is 3; In the second case: 1->2; 1->3 the cost is 2;
#include <iostream> #include <cstdio> #include <cstring> #include <algorithm> using namespace std; const int maxn=11000; struct Edge { int to,next,w; }edge[2*maxn]; int Adj[maxn],Size; void init() { memset(Adj,-1,sizeof(Adj)); Size=0; } void Add_Edge(int u,int v,int weight) { edge[Size].to=v; edge[Size].next=Adj[u]; edge[Size].w=weight; Adj[u]=Size++; } int n,S,K; int dp[maxn][20]; bool vis[maxn]; void dfs(int u) { vis[u]=true; for(int i=Adj[u];~i;i=edge[i].next) { int v=edge[i].to; int w=edge[i].w; if(vis[v]) continue; dfs(v); for(int j=K;j>=0;j--) { dp[u][j]+=dp[v][0]+2*w; for(int jj=0;jj<=j;jj++) { dp[u][j]=min(dp[u][j],dp[u][j-jj]+dp[v][jj]+jj*w); } } } } int main() { while(scanf("%d%d%d",&n,&S,&K)!=EOF) { init(); for(int i=1;i<n;i++) { int a,b,w; scanf("%d%d%d",&a,&b,&w); Add_Edge(a,b,w); Add_Edge(b,a,w); } memset(dp,0,sizeof(dp)); memset(vis,0,sizeof(vis)); dfs(S); printf("%d\n",dp[S][K]); } return 0; }
HDOJ 4003 Find Metal Mineral,布布扣,bubuko.com
标签:des style http color java os io strong
原文地址:http://blog.csdn.net/ck_boss/article/details/38467507