题意:

  王国地图为 n 个节点的根树,首都为 1,

  m 个旅行家要去不同的终点旅游,他们分别有各自的预算,如果路上总费用超过预算就不去了

  给每条路定价, 让赚的钱最多

分析:

    DP[i][j]表示当从首都到城市i的路径花费为j时,以i为根的子树中的点作为目的城市的旅行者的最大花费.

  只需要考虑j值等于0或等于某位旅行者预算的情况,所以dp的状态数是O(NM)的.

  状态转移方程式:

  DP[i][j] = j* n(i,j) + ∑​max(DP[k][j​i]) (ji >= j)
    

    ( n(i,j)为以i作为目标城市且预算不小于j的旅行者数量,

      k 为 i 的所有子代节点

      ​max(DP[k][j​i]) 为节点k的所有ji >= j 的 DP[k][j​i] 的最大值 )

  上式max(DP[k, j​i]) (ji >= j) 可用 DP[i][j] = max(DP[i][j], DP[i][j+1]) 递推而得
则转移方程式为:

DP[i][j] = j* n(i,j) + DP[i][j].

  确定完每一点的最大花费总和后,两点的最大花费总和相减即为该边的定价

  注意起点的花费一定为 0 !

  1. #include <iostream>
  2. #include <cstring>
  3. #include <cstdio>
  4. #include <vector>
  5. #include <algorithm>
  6. using namespace std;
  7. #define LL long long
  8. const int MAXN = ;
  9. int t, n, m, s;
  10. vector<int> mp[MAXN], id[MAXN];
  11. LL dp[MAXN][MAXN];
  12. LL v[MAXN];
  13. int edge[MAXN][MAXN];
  14. int bst[MAXN][MAXN];
  15. LL ans[MAXN];
  16. LL a[MAXN];
  17. void DFS(int x,int fa)
  18. {
  19. for (int i = ; i < mp[x].size(); i++)
  20. {
  21. if (mp[x][i] != fa) DFS(mp[x][i], x);
  22. }
  23. for (int j = s-; j >= ; j--)
  24. {
  25. int t = ;
  26. for (int i = ; i < id[x].size(); i++)
  27. if (a[id[x][i]] >= v[j]) t++;
  28. dp[x][j] += t*v[j]; //j* n(i,j)
  29. for (int i = ; i < mp[x].size(); i++)
  30. {
  31. if (mp[x][i] == fa) continue;
  32. int p = mp[x][i];
  33. dp[x][j] += dp[p][j];
  34. }
  35. if (j == s- || dp[x][j+] <= dp[x][j])
  36. {
  37. bst[x][j] = j;
  38. }
  39. else
  40. {
  41. dp[x][j] = dp[x][j+];
  42. bst[x][j] = bst[x][j+];
  43. }
  44. }
  45. }
  46. void DFS2(int x,int a,int fa)
  47. {
  48. for (int i = ; i < mp[x].size(); i++)
  49. {
  50. int e = mp[x][i];
  51. if (e == fa) continue;
  52. int b = bst[e][a];
  53. ans[edge[x][e]] =v[b]- v[a];
  54. DFS2(e,b,x);
  55. }
  56. }
  57. int main()
  58. {
  59. scanf("%d", &t);
  60. while (t--)
  61. {
  62. scanf("%d%d", &n, &m);
  63. for (int i = ; i <= n; i++) mp[i].clear(), id[i].clear();
  64. memset(dp,,sizeof(dp));
  65. for (int i = ; i < n ;i++)
  66. {
  67. int u,v; scanf("%d%d", &u, &v);
  68. mp[u].push_back(v);
  69. mp[v].push_back(u);
  70. edge[u][v] = edge[v][u] = i;
  71. }
  72. for (int i = ; i <= m; i++)
  73. {
  74. int u; scanf("%d%lld",&u, &a[i]);
  75. v[i] = a[i];
  76. id[u].push_back(i);
  77. }
  78. id[].clear();//起始点不计费!
  79. v[] = ;
  80. sort(v,v++m);
  81. s = unique(v,v++m) - v;
  82. DFS(,-);
  83. DFS2(,,-);
  84. printf("%lld\n",dp[][]);
  85. for (int i = ; i < n-; i++)
  86. printf("%lld ",ans[i]);
  87. printf("%lld\n", ans[n-]);
  88. }
  89. }

HDU 5815 - Golden Week的更多相关文章

  1. HDU 3820 Golden Eggs (SAP | Dinic)

    Golden Eggs Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total ...

  2. HDU 4814 Golden Radio Base 小模拟

    链接:http://acm.hdu.edu.cn/showproblem.php?pid=4814 题意:黄金比例切割点是,如今要求把一个10进制的的数转化成一个phi进制的数,而且不能出现'11'的 ...

  3. HDU 4814 Golden Radio Base 模拟

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4814 题目大意: 把一个正整数表示为φ进制, φ = (1+√5)/2 . 且已知: 1. φ + 1 ...

  4. HDU 4818 Golden Radio Base (2013长春现场赛B题)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4814 进制转换. 现场根据题目给的两个公式,不断更新!!! 胡搞就可以了. 现场3A,我艹,一次循环开 ...

  5. HDU 3820 Golden Eggs

    http://acm.hdu.edu.cn/showproblem.php?pid=3820 题意:n*m的格子,每个格子放金蛋或银蛋,每个格子的金蛋和银蛋都有一个对应的点权,如果有两个金蛋相连,则需 ...

  6. HDU 3820 Golden Eggs( 最小割 奇特建图)经典

    Golden Eggs Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Tota ...

  7. hdu 4814 Golden Radio Base

    详解见:http://blog.csdn.net/tri_integral/article/details/18666797 #include<cstdio> #include<cs ...

  8. Todo List

    Contest 11.13 2016ACM/ICPC亚洲区青岛站(5/13, solved 7/13) Training 11.06 2016年中国大学生程序设计竞赛(合肥)(solved 6/10) ...

  9. Golden Eggs HDU - 3820(最小割)

    Golden Eggs Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total ...

随机推荐

  1. webform 验证控件

    验证: 一.非空验证  RequiredFieldValidator ErrorMessage - 验证出错后的提示信息 ControlToValidate - 要验证的控件的ID Display - ...

  2. 三个重要的游标sp_cursoropen

    請問這三個存諸過程的作用是什么﹖ sp_cursoropen, sp_cursorfetch, sp_cursorclose API 服务器游标实现  SQL Server OLE DB 提供程序. ...

  3. worklight 中添加时间控件

    在我们使用worklight开发的过程中,由于文档的不开源和插件的缺少,总是自己琢磨很多东东,更有胜者 需要调用源代码实现某些不易实现的功能.在这里把实现的功能代码贴出来,如有不足之处还望指正! 实现 ...

  4. jquery mobile转场时加载js失效

    jquery mobile拦截了所有的http请求,并使用ajax请求取代传统的http.请求发出后,框架会将请求的内容插入到页面中data- role="page"的部分,取代原 ...

  5. <c:if>标签

    <c:if>的用途就和我们一般在程序中用的if一样. 语法 语法1:没有本体内容(body) <c:if test="testCondition" var=&qu ...

  6. UIViewController的生命周期及iOS程序执行顺序

    UIViewController的生命周期及iOS程序执行顺序     当一个视图控制器被创建,并在屏幕上显示的时候. 代码的执行顺序1. alloc                         ...

  7. Keil C51 详细设置

    一.target名更改 打开Keil后,左侧Project Workspace中的target可改,方法:右击Target——Manage Compnents——双击待修改项即可,若要添加,使用对话框 ...

  8. Android CursorAdapter

    CursorAdapter 继承于BaseAdapter是个虚类,它为cursor和ListView提供了连接的桥梁.            public abstract class     Cur ...

  9. Prime Palindrome Golf

    Prime Palindrome Golf Do you know how to play Prime Palindrome Golf? You are given a number and your ...

  10. 2015第15周六Java线程池

    Java里面线程池的顶级接口是Executor,但是严格意义上讲Executor并不是一个线程池,而只是一个执行线程的工具.真正的线程池接口是ExecutorService. 比较重要的几个类: Ex ...