题意:
题解:
我们设dp[i][j] 表示已i为根节点,放j个机器人的最小话费
那么:
dp(i,j)=(dp(son,0)+cast[son]*2)(子树没有停留机器人)+min(dp[p][m-y]+y*cost[son]+dp[son][y])(子树停留了y个机器人)
//meek #include <iostream> #include <cstdio> #include <cmath> #include <string> #include <cstring> #include <algorithm> #include <queue> #include <map> #include <set> #include <stack> #include <sstream> #include <vector> using namespace std ; typedef long long ll; #define mem(a) memset(a,0,sizeof(a)) #define pb push_back #define fi first #define se second #define MP make_pair inline ll read() { ll x=0,f=1; char ch=getchar(); while(ch<‘0‘||ch>‘9‘) { if(ch==‘-‘)f=-1; ch=getchar(); } while(ch>=‘0‘&&ch<=‘9‘) { x=x*10+ch-‘0‘; ch=getchar(); } return x*f; } //**************************************** const int N=500000+100; const ll inf = 1ll<<61; const int mod= 1000000007; vector< pair<int ,int> >G[N]; int dp[N][11],n,S,K,u,v,w; void dfs(int x,int pre) { for(int i=0;i<G[x].size();i++) { if(G[x][i].fi==pre) continue; int son=G[x][i].fi,cost=G[x][i].se; dfs(G[x][i].fi,x); for(int k=K;k>=0;k--) { dp[x][k]+=dp[son][0]+cost*2; for(int y=1;y<=k;y++) { dp[x][k]=min(dp[x][k],dp[x][k-y]+dp[son][y]+cost*y); } } } } void init() { for(int i=0;i<=n;i++) G[i].clear(); mem(dp); } int main() { while(~(scanf("%d%d%d",&n,&S,&K))) { init(); for(int i=1;i<n;i+=1) { scanf("%d%d%d",&u,&v,&w); G[u].pb(MP(v,w)); G[v].pb(MP(u,w)); } dfs(S,-1); cout<<dp[S][K]<<endl; } return 0; }
HDU4003 Find Metal Mineral 树形DP
原文:http://www.cnblogs.com/zxhl/p/5030703.html