题目链接: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 的节点记录下来即可。

 #include <bits/stdc++.h>
using namespace std;
#define ll long long
#define ull unsigned long long
#define mst(a,b) memset((a),(b),sizeof(a))
#define mp(a,b) make_pair(a,b)
#define pi acos(-1)
#define pii pair<int,int>
#define pb push_back
const int INF = 0x3f3f3f3f;
const double eps = 1e-;
const int MAXN = 1e5 + ;
const int MAXM = 1e3 + ;
const ll mod = ; int n;
ll p,ans;
vector<pair<int,ll> >vec[MAXN];
ll dist[MAXN],dp[MAXN];
int q[MAXN]; ll sqr(ll x) {
return x * x;
} ll getup(int j,int k) {
return dp[j] + sqr(dist[j]) - (dp[k] + sqr(dist[k]));
} ll getdown(int j,int k) {
return 2ll * (dist[j] - dist[k]);
} void dfs(int u,int fa,int st,int en) {
dp[u] = dist[u] * dist[u];
int head = st, tail = en;
while(head + < tail && getup(q[head + ],q[head]) <= dist[u] * getdown(q[head + ],q[head])) head++;
dp[u] = min(dp[u], dp[q[head]] + sqr(dist[u] - dist[q[head]]) + p);
while(head + < tail && getup(u,q[tail - ]) * getdown(q[tail - ],q[tail - ]) <= getup(q[tail - ],q[tail - ]) * getdown(u,q[tail - ]))
tail--;
q[tail++] = u;
int pre = u;
ans = max(ans, dp[u]);
for(int i = ; i < vec[u].size(); i++) {
int v = vec[u][i].first;
ll w = vec[u][i].second;
if(v == fa) continue;
dist[v] = dist[u] + w;
dfs(v,u,head,tail);
}
q[tail - ] = pre;
} int main() {
#ifdef local
freopen("data.txt", "r", stdin);
#endif
int t;
scanf("%d",&t);
while(t--) {
scanf("%d%lld",&n,&p);
for(int i = ; i <= n; i++) {
vec[i].clear();
}
for(int i = ; i < n; i++) {
int u,v;
ll w;
scanf("%d%lld%lld",&u,&v,&w);
vec[u].push_back(make_pair(v,w));
vec[v].push_back(make_pair(u,w));
}
dist[] = ;
int head = , tail = ;
q[tail++] = ;
ans = ;
dfs(,,,);
printf("%lld\n",ans);
}
return ;
}

ACM-ICPC 2016 沈阳赛区现场赛 I. The Elder && HDU 5956(斜率DP)的更多相关文章

  1. ACM-ICPC 2017 沈阳赛区现场赛 M. Wandering Robots && HDU 6229(思维+期望)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6229 参考题解:https://blog.csdn.net/lifelikes/article/det ...

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

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

  3. HDU 4046 Panda (ACM ICPC 2011北京赛区网络赛)

    HDU 4046 Panda (ACM ICPC 2011北京赛区网络赛) Panda Time Limit: 10000/4000 MS (Java/Others)    Memory Limit: ...

  4. ACM总结——2017ACM-ICPC北京赛区现场赛总结

    现在距离比赛结束已经过了一个多星期了,也是终于有时间写下心得了.回来就是被压着做项目,也是够够的. 这次比赛一样是我和两个学弟(虽然是学弟,但我的实力才是最弱的T_T)一起参加的,成绩的话打铁,算是情 ...

  5. [刷题]ACM/ICPC 2016北京赛站网络赛 第1题 第3题

    第一次玩ACM...有点小紧张小兴奋.这题目好难啊,只是网赛就这么难...只把最简单的两题做出来了. 题目1: 代码: //#define _ACM_ #include<iostream> ...

  6. ACM-ICPC 2016 大连赛区现场赛 K. Guess the number && HDU 5981(思维+DP)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5981 题意:A在[L, R]之间随机选取一个数X,之后B来猜这个数,如果猜的数比X小,那么A就告诉B猜 ...

  7. ACM-ICPC 2015 沈阳赛区现场赛 I. Triple && HDU 5517(二维BIT)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5517 题意:有二元组(a,b),三元组(c,d,e).当b == e时它们能构成(a,c,d)然后,当 ...

  8. ACM-ICPC 2015 沈阳赛区现场赛 F. Frogs && HDU 5514(容斥)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5514 题意:有m个石子围成一圈, 有n只青蛙从跳石子, 都从0号石子开始, 每只能越过xi个石子.问所 ...

  9. ACM-ICPC 2017 沈阳赛区现场赛 G. Infinite Fraction Path && HDU 6223(BFS)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6223 参考题解:https://blog.csdn.net/qq_40482495/article/d ...

随机推荐

  1. 数据结构:BF算法

    贴上源代码: #include<iostream> using namespace std; int BF(char S[],char T[]) { int i,j; i = j = 0; ...

  2. ubuntu 18.04 LTS 安装ROS系统

    不同的ubuntu系统对应着不同的ROS版本,如果装错了就会提示 E:无法定位软件包 ROS有Melodic.Lunar.Kinetic不同的种类对应着不同的ubuntu版本 Melodic主要对应: ...

  3. 【Python基础】07_Python中的模块

    1.模块的概念 模块 就好比 工具包,要想使用这个工具包中的工具,就需要 导入import 这个模块 每一个以扩展名 .py 结尾的 Python源代码文件 都是一个 模块 在模块中定义的 全局变量. ...

  4. 【搜索】Partition problem

    题目链接:传送门 题面: [题意] 给定2×n个人的相互竞争值,请把他们分到两个队伍里,如果是队友,那么竞争值为0,否则就为v[i][j]. [题解] 爆搜,C(28,14)*28,其实可以稍加优化, ...

  5. JVM描述符标识字符含义

    标识字符 含义 B byte C char D double F float I int J long S short Z boolean V void L 对象类型,如Ljava/lang/Obje ...

  6. Django rest-framework框架-用户权限实例

    简单实例: class MyPermission(object): ''' 权限控制类 ''' def has_permission(self,request,view): if request.us ...

  7. LeetCode:1179.重新格式化部门表

    题目链接:https://leetcode-cn.com/problems/reformat-department-table/ 题目 部门表 Department: +--------------- ...

  8. ThreeJS 3d模型简介

    本文主要是对Threejs中加载模型的支持种类进行简单的知识科普. 3ds (.3ds) 3ds是3ds max通用储存文件格式.使用的范围更宽,可被更多的软件识别使用. amf (.amf) AMF ...

  9. go语言入门(9)文本文件处理

    1,字符串处理 字符串在开发中经常用到,包括用户的输入,数据库读取的数据等,我们经常需要对字符串进行分割.连接.转换等操作,我们可以通过Go标准库中的strings和strconv两个包中的函数进行相 ...

  10. String s=new String("xyz");创建了几个String Object?二者之前的区别是什么?

    两个.第一个对象是字符串常量"xyz",第二个对象是new String("xyz")的时候产生的,在堆中分配内存给这个对象,只不过这个对象的内容是指向字符串常 ...