题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5956

题意:一颗树上每条边有个权值,每个节点都有新闻要送到根节点就是1节点,运送过程中如果不换青蛙就是走过的所有边权之和的平方,如果换就每次更换要加上P,也就是求“每个节点到根节点这段路径切分成几块之后 [每块的权值和的平方加上(块个数-1)*P] 的最小值”。然后找到所有节点中消耗最大的那个是多少。

题解:设 dist[ i ] 表示节点 i 到根节点的距离,有 dp[ i ] = min(dp[ j ] + ( dist[ i ] - dist[ j ] ) ^ 2 + p),显然是斜率dp,需要注意的是这是在树上做斜率dp,当遍历了一个节点的某一棵子树后,遍历该节点的下一棵子树要恢复到之前的状态,可以考虑 dfs 过程中多传两个参数代表当前队列的 head 和 tail,而遍历完一棵子树后可能改变的是 tail,所以在比遍历之前把 tail 的节点记录下来即可。

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 #define ll long long
 4 #define ull unsigned long long
 5 #define mst(a,b) memset((a),(b),sizeof(a))
 6 #define mp(a,b) make_pair(a,b)
 7 #define pi acos(-1)
 8 #define pii pair<int,int>
 9 #define pb push_back
10 const int INF = 0x3f3f3f3f;
11 const double eps = 1e-6;
12 const int MAXN = 1e5 + 10;
13 const int MAXM = 1e3 + 10;
14 const ll mod = 100000073;
15
16 int n;
17 ll p,ans;
18 vector<pair<int,ll> >vec[MAXN];
19 ll dist[MAXN],dp[MAXN];
20 int q[MAXN];
21
22 ll sqr(ll x) {
23     return x * x;
24 }
25
26 ll getup(int j,int k) {
27     return dp[j] + sqr(dist[j]) - (dp[k] + sqr(dist[k]));
28 }
29
30 ll getdown(int j,int k) {
31     return 2ll * (dist[j] - dist[k]);
32 }
33
34 void dfs(int u,int fa,int st,int en) {
35     dp[u] = dist[u] * dist[u];
36     int head = st, tail = en;
37     while(head + 1 < tail && getup(q[head + 1],q[head]) <= dist[u] * getdown(q[head + 1],q[head])) head++;
38     dp[u] = min(dp[u], dp[q[head]] + sqr(dist[u] - dist[q[head]]) + p);
39     while(head + 1 < tail && getup(u,q[tail - 1]) * getdown(q[tail - 1],q[tail - 2]) <= getup(q[tail - 1],q[tail - 2]) * getdown(u,q[tail - 1]))
40         tail--;
41     q[tail++] = u;
42     int pre = u;
43     ans = max(ans, dp[u]);
44     for(int i = 0; i < vec[u].size(); i++) {
45         int v = vec[u][i].first;
46         ll w = vec[u][i].second;
47         if(v == fa) continue;
48         dist[v] = dist[u] + w;
49         dfs(v,u,head,tail);
50     }
51     q[tail - 1] = pre;
52 }
53
54 int main() {
55 #ifdef local
56     freopen("data.txt", "r", stdin);
57 #endif
58     int t;
59     scanf("%d",&t);
60     while(t--) {
61         scanf("%d%lld",&n,&p);
62         for(int i = 1; i <= n; i++) {
63             vec[i].clear();
64         }
65         for(int i = 1; i < n; i++) {
66             int u,v;
67             ll w;
68             scanf("%d%lld%lld",&u,&v,&w);
69             vec[u].push_back(make_pair(v,w));
70             vec[v].push_back(make_pair(u,w));
71         }
72         dist[1] = 0;
73         int head = 0, tail = 0;
74         q[tail++] = 1;
75         ans = 0;
76         dfs(1,0,0,1);
77         printf("%lld\n",ans);
78     }
79     return 0;
80 }

转载于:https://www.cnblogs.com/scaulok/p/9771275.html

ACM-ICPC 2016 沈阳赛区现场赛 I. The Elder HDU 5956(斜率DP)相关推荐

  1. 2016 ACM/ICPC亚洲区青岛站现场赛(部分题解)

    摘要 本文主要列举并求解了2016 ACM/ICPC亚洲区青岛站现场赛的部分真题,着重介绍了各个题目的解题思路,结合详细的AC代码,意在熟悉青岛赛区的出题策略,以备战2018青岛站现场赛. HDU 5 ...

  2. ACM-ICPC 2018 沈阳赛区现场赛 K. Let the Flames Begin (约瑟夫环问题)

    题目链接: 题意:有 n 个人围成一个圈,从 1 开始报到第 k 个人出环,问第 m 个出环的人是谁,n.m.k <= 1e18 且 min(m,k)<= 2e6. 题解:容易得出O(m) ...

  3. ACM-ICPC 2018 沈阳赛区现场赛 E. The Kouga Ninja Scrolls (切比雪夫距离+线段树)

    题目链接: 题意:在二维平面上有 n 个人,每个人有一个位置(xi, yi)和门派 ci,m 个操作:①改变第 k 个人的位置:②改变第 k 个人的门派:③询问区间[l,r]之间不同门派的两个人的最大 ...

  4. 2016ACM/ICPC亚洲区沈阳站-重现赛(感谢东北大学)

    目录 A Thickest Burger B Relative atomic mass C Recursive sequence · 矩阵快速幂 E Counting Cliques · 暴力 H G ...

  5. 2018年 ACM/ICPC亚洲区域赛 青岛赛区现场赛 比赛总结

    首先祝贺自己收获了ACM生涯中的第二枚铜牌. 首先吐槽一下中石油: 周六早上来到中国石油大学,连个志愿者小姐姐都没看到.(但是看到了女装大佬).报完到之后发现教练少了一张午餐券(要不要这么粗心).为了 ...

  6. 2016ACM/ICPC亚洲区大连站现场赛题解报告(转)

    http://blog.csdn.net/queuelovestack/article/details/53055418 下午重现了一下大连赛区的比赛,感觉有点神奇,重现时居然改了现场赛的数据范围,原 ...

  7. 2016ACM/ICPC亚洲区大连站现场赛题解报告

    此文章可以使用目录功能哟↑(点击上方[+]) 下午重现了一下大连赛区的比赛,感觉有点神奇,重现时居然改了现场赛的数据范围,原本过的人数比较多的题结果重现过的变少了,而原本现场赛全场过的人最少的题重现做 ...

  8. 暑期ACM模拟赛--2017ACM/ICPC亚洲区沈阳站-重现赛 【待补】

    A - BBP Formula HDU - 6217 (数学问题+公式推导+快速幂) F - Heron and His Triangle HDU - 6222  (数学问题+海伦公式+大数) I - ...

  9. hdu 4442 Physical Examination (2012年金华赛区现场赛A题)

    昨天模拟赛的时候坑了好久,刚开始感觉是dp,仔细一看数据范围太大. 题目大意:一个人要参加考试,一共有n个科目,每个科目都有一个相应的队列,完成这门科目的总时间为a+b*(前面已完成科目所花的总时间) ...

  10. 2011年第36届大连赛区现场赛Board

    First to solve problem Solved problem Attempted problem S# School Rk Team Slv. Time A 2/18 B 15/89 C ...

最新文章

  1. AI技术在图像水印处理中的应用
  2. virtual keyboard
  3. 对象属性对话框只能放大不能缩小
  4. win7中能对窗口的排列方法是_win7系统窗口排列方式怎么修改?修改窗口排列方式方法...
  5. 七桥问题c语言程序数据结构,数据结构与算法学习——图论
  6. linux生成文件自带时间,linux生成固定日期文件及删除一定日期前的文件
  7. linux: chmod,chown命令详解
  8. 微服务(MicroServices)
  9. 作业帮:给定一个整数数组,找出其中两个数相加等于目标值(去重set)
  10. 近年来量子计算机,近年来量子计算机研究的进展和困难.doc
  11. Choose and divide(唯一分解定理)
  12. Ubuntu安装gcc 以及g++
  13. java控制台输出图片
  14. JAVA————简单的图形绘制界面(教程)
  15. cocos shader 之 黑白滤镜
  16. 西北农林科技大学考研计算机大纲,2021年西北农林科技大学考研真题大纲参考书目...
  17. 【2024】末两位数
  18. 移动学习 AndroidStudio内存优化分析—hprof文件分析
  19. 如何用transition实现翻书动画效果
  20. 最常用的器件PCB封装尺寸大全

热门文章

  1. 3.7 App.vue-常用配置【uni-app教程uniapp教程(黄菊华-跨平台开发系列教程)】
  2. Python Flask学习_使用flask-login实现认证蓝本(一)
  3. 英语介词at、in、on常见用法(时间、地点、方位)
  4. 什么是PMU(PMIC)
  5. 很勤奋的学画画从零基础开始学习,到成为一名原画师需要几年?
  6. qsnctf 哥哥打篮球 wp
  7. 如何在VirtualBox上安装和安装Windows Home Server“ Vail” Beta
  8. vb整合多个excel表格到一张_如何使用VB实现多个excel表格合并在一个EXCEL表格里面...
  9. DC-DC升压芯片MP9185
  10. 通过SQL语句数据库简繁体转换