hdu 4003(树形dp)
来源:互联网 发布:linux多线程编程 书籍 编辑:程序博客网 时间:2024/06/06 19:01
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4003
思路:dp[i][j]表示以i为根选择j个机器人的最小花费,然后就是背包了:dp[u][i]=min(dp[u][i],dp[u][i-j]+dp[v][j]+j*w)(1<<j<<i,u是v的根)。值得注意的是dp[u][0]的意义,dp[i][0]表示以i为根的子树派一个机器人遍历完整棵子树后又回到i的花费。
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 #include<vector> 6 using namespace std; 7 #define MAXN 10100 8 #define inf 1<<30 9 10 struct Edge{11 int v,w;12 Edge(int vv,int ww):v(vv),w(ww){}13 };14 15 int n,s,k;16 int dp[MAXN][20];17 vector<vector<Edge> >G;18 19 void dfs(int u,int father)20 {21 for(int i=0;i<G[u].size();i++){22 int v=G[u][i].v,w=G[u][i].w;23 if(v==father)continue;24 dfs(v,u);25 for(int i=k;i>=0;i--){26 dp[u][i]+=dp[v][0]+2*w;//v所在子树不放置机器人,那么必然要派一个机器人从u到v去遍历v所在子树并且回到u.27 for(int j=1;j<=i;j++){ //子树放置1-j个机器人28 dp[u][i]=min(dp[u][i],dp[u][i-j]+dp[v][j]+j*w);29 }30 }31 }32 }33 34 int main()35 {36 int u,v,w;37 while(~scanf("%d%d%d",&n,&s,&k)){38 G.clear();39 G.resize(n+2);40 for(int i=1;i<n;i++){41 scanf("%d%d%d",&u,&v,&w);42 G[u].push_back(Edge(v,w));43 G[v].push_back(Edge(u,w));44 }45 memset(dp,0,sizeof(dp));46 dfs(s,-1);47 printf("%d\n",dp[s][k]);48 }49 return 0;50 }
0 0
- hdu 4003 树形DP
- hdu 4003(树形dp)
- HDU-4003-树形dp
- HDU 4003 树形DP+背包
- hdu 4003 树形dp+分组背包
- hdu 4003 树形dp+分组背包
- HDU 4003 (树形DP + 分组背包)
- HDU 4003 Find Metal Mineral 树形DP
- hdu 4003 Find Metal Mineral 树形DP
- HDU 4003 树形dp+分组背包
- HDU-4003 Find Metal Mineral 树形dp
- 树形dp hdu Computer
- 【树形DP】hdu 1520
- hdu 1054 #树形DP
- hdu 4303 树形dp
- hdu 4340 树形dp
- hdu 4340 树形DP
- HDU 4340 树形DP
- hdu 4715(打表)
- hdu 4708(暴力+找规律)
- hdu 3905(dp)
- hdu 4714(树形dp)
- hdu 3899(树形dp)
- hdu 4003(树形dp)
- hdu 2196(求树上每个节点到树上其他节点的最远距离)
- hdu 2809(状压dp)
- hdu 1561(树形dp)
- hdu 1520(简单树形dp)
- hdu 1513(dp+滚动数组)
- hdu 4240在(最大流)
- 大端法、小端法、网络字节序
- hdu 4722(记忆化搜索)