[HDU5956]The Elder
题面在这里
题意
一个王国中的所有城市构成了一棵有根树,其根节点为首都,编号为1
树有边权,城市的记者每次向祖先移动\(d\)的路程需要的代价为\(d^2\),
如果祖先不是根还需要加上\(p\),求每个非根节点的记者移动到首都的最小代价
sol
考虑朴素的DP,设\(f[i]\)表示第\(i\)号节点到达根节点的最小代价,
\(s[i]\)表示\(i\)到根节点的距离,那么有
\]
初始状态为\(f[1]=-p\)
斜率优化:
\]
那么考虑插点\((2s[j],f[j]+s[j]^2)\),询问斜率\(k_i=s[i]\);
树上斜率优化——可持久化单调队列
由于是在树上做,那么我们需要支持撤销前一次的操作;
我们对于记录一个栈,记录推到这个节点时弹出了哪些节点,
撤回的时候在队列中删掉当前节点,把之前弹出的节点放回去即可
这样的时间复杂度应该仍为\(O(n)\)
代码
#include<bits/stdc++.h>
#include<algorithm>
#include<iostream>
#include<cstdlib>
#include<iomanip>
#include<cstring>
#include<complex>
#include<vector>
#include<cstdio>
#include<string>
#include<bitset>
#include<cmath>
#include<queue>
#include<stack>
#include<map>
#include<set>
#define mp make_pair
#define pub push_back
#define puf push_front
#define pob pop_back
#define pof pop_front
#define RG register
#define il inline
using namespace std;
typedef unsigned long long ull;
typedef vector<int>VI;
typedef long long ll;
typedef double dd;
const dd eps=1e-10;
const int mod=1e8;
const int N=1000010;
il ll read(){
RG ll data=0,w=1;RG char ch=getchar();
while(ch!='-'&&(ch<'0'||ch>'9'))ch=getchar();
if(ch=='-')w=-1,ch=getchar();
while(ch<='9'&&ch>='0')data=data*10+ch-48,ch=getchar();
return data*w;
}
il void file(){
freopen(".in","r",stdin);
freopen(".out","w",stdout);
}
ll T,n,p,f[N],s[N];
int head[N],nxt[N<<1],to[N<<1],val[N<<1],cnt;
il void add(ll u,ll v,ll w){
to[++cnt]=v;
nxt[cnt]=head[u];
val[cnt]=w;
head[u]=cnt;
}
int L=1,R;ll qx[N],qy[N];
int cal[N],top;ll calx[N],caly[N];
il void cancel(int u){
R--;
while(cal[top]==u){
R++;qx[R]=calx[top];qy[R]=caly[top];top--;
}
}
il void insert(int u,ll x,ll y){
while(L<R&&(qy[R]-qy[R-1])*(x-qx[R])>=(y-qy[R])*(qx[R]-qx[R-1])){
cal[++top]=u;calx[top]=qx[R];caly[top]=qy[R];R--;
}
R++;qx[R]=x;qy[R]=y;
}
il int check(ll k,int mid){
if(mid!=R&&k*(qx[mid+1]-qx[mid])>qy[mid+1]-qy[mid])
return 1;
if(mid!=L&&k*(qx[mid]-qx[mid-1])<qy[mid]-qy[mid-1])
return -1;
return 0;
}
//二分斜率
il ll query(ll k){
RG int l=L,r=R,mid,ret;
while(l<=r){
mid=(l+r)>>1;
ret=check(k,mid);
if(!ret)return qy[mid]-k*qx[mid];
else if(ret==1)l=mid+1;
else if(ret==-1)r=mid-1;
}
}
void dfs_DP(int u,int fa){
if(u!=1){
f[u]=query(s[u])+s[u]*s[u]+p;
insert(u,2*s[u],f[u]+s[u]*s[u]);
}
else insert(u,0,-p);
for(RG int i=head[u];i;i=nxt[i]){
RG int v=to[i];if(v==fa)continue;
s[v]=s[u]+val[i];dfs_DP(v,u);
}
cancel(u);
}
il void solve(){
memset(head,0,sizeof(head));cnt=0;L=1;R=0;
n=read();p=read();
RG ll u,v,w;
for(RG int i=1;i<n;i++){
u=read();v=read();w=read();
add(u,v,w);add(v,u,w);
}
dfs_DP(1,0);
RG ll maxn=0;
for(RG int i=1;i<=n;i++)
maxn=max(maxn,f[i]);
printf("%lld\n",maxn);
}
int main()
{
T=read();while(T--)solve();return 0;
}
[HDU5956]The Elder的更多相关文章
- 《The Elder Scrolls V: Skyrim》百般冷门却强力职业
<The Elder Scrolls V: Skyrim>百般冷门却强力职业 1.有如成龙平常的杂耍型战斗窃贼 每次看帖都察觉大伙一贯在强调窃贼不需要防御,窃贼不需要血,窃贼就是一击致命, ...
- hdu 5956 The Elder
http://acm.hdu.edu.cn/showproblem.php?pid=5956 转移方程:dp[i]=(dis[i]-dis[j])*(dis[i]-dis[j])+P+dp[j] 斜率 ...
- HDU 5956 The Elder (树上斜率DP)
题意:给定上一棵树,然后每条边有一个权值,然后每个点到 1 的距离有两种,第一种是直接回到1,花费是 dist(1, i)^2,还有另一种是先到另一个点 j,然后两从 j 向1走,当然 j 也可以再向 ...
- HDU - 59562016ACM/ICPC亚洲区沈阳站I - The Elder 树上斜率优化dp
题意:给定上一棵树,然后每条边有一个权值,然后每个点到 1 的距离有两种,第一种是直接回到1,花费是 dist(1, i)^2,还有另一种是先到另一个点 j,然后两从 j 向1走,当然 j 也可以再向 ...
- 【HDOJ5956】The Elder(树形DP,斜率优化)
题意:有一棵n个点的有根树,每条边上有一个边权.给定P,从i跳到它的祖先j的费用是距离的平方+P,问所有点中到根节点1的总花费最大值 n<=1e5,p<=1e6,w<=1e2 思路: ...
- The Elder HDU - 5956
/* 树上斜率优化 一开始想的是构造出一个序列 转化成一般的dp但是可能被卡 扫把状的树的话可能变成n*n 其实可以直接在树上维护这个单调队列 dfs虽然搞得是一棵树,但是每次都是dfs到的都是一个序 ...
- ACM-ICPC 2016 沈阳赛区现场赛 I. The Elder && HDU 5956(斜率DP)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5956 题意:一颗树上每条边有个权值,每个节点都有新闻要送到根节点就是1节点,运送过程中如果不换青蛙就是 ...
- LuoguP7369 [COCI2018-2019#4] Elder 题解
Content 有一个魔杖最初在 \(Z\) 巫师中.经过 \(n\) 轮较量,第 \(i\) 轮中,\(Z_{i,1}\) 巫师打败了 \(Z_{i,2}\) 巫师.如果一个巫师打败了拥有魔杖的巫师 ...
- poj 1251 Jungle Roads (最小生成树)
poj 1251 Jungle Roads (最小生成树) Link: http://poj.org/problem?id=1251 Jungle Roads Time Limit: 1000 ...
随机推荐
- 2017年PHP程序员未来路在何方?(转载)
PHP 从诞生到现在已经有 20 多年历史,从 Web 时代兴起到移动互联网退潮,互联网领域各种编程语言和技术层出不穷, Node.js . GO . Python 不断地在挑战 PHP 的地位.这些 ...
- .Net Core On Liunx 环境搭建之 Docker 容器和Nginx
上一篇文章安装了Mysql8数据库,接下开始安装Docker和Nginx 我的思路是这样的,用Docker当运行环境的虚拟机,Nginx当Http服务器用来做反向代理. 服务器环境:阿里云服务器,操作 ...
- php柱状图多系列动态实现
<?php require_once 'data.php'; require_once 'jpgraph/src/jpgraph.php'; require_once"jpgraph/ ...
- 【PHP项目】产品新增的多图上传
产品新增:多图上传 1:html的更改 在 type=file的input框中添加multiple="multiple" name属性中必须添加[] ,否则$_FILES只能接收最 ...
- Python学习:1.快速搭建python环境
一.安装python 现在python有两个比较大的版本一个是python3.x一个是python2.x,python3.x相当于与python2.x是一个比较大的升级,但是python3.x没有向下 ...
- Redis缓存数据库的安装与配置(1)
1.安装 tarxf redis-3.2.5.tar.gz cd redis-3.2.5 make mkdir -p /usr/local/redis/bin src目录下这些文件作用如下 redis ...
- Make命令完全详解教程
Make命令完全详解教程 无论是在Linux还是在Unix环境中,make都是一个非常重要的编译命令.不管是自己进行项目开发还是安装应用软件,我们都经常要用到make或make install.利用m ...
- Java线程和多线程(九)——死锁
Java中的死锁指的就是一种多于两个线程永远阻塞的特殊状况.Java中的死锁状态至少需要多于两个线程以及资源的时候才会产生.这里,我写了一个产生死锁的程序,并且讲下如何分析死锁. 首先来看一下产生死锁 ...
- ExtJs工具篇(2)——Aptana Studio 3 汉化
本身用的是中文版本的,但是输入一些中文后,竟然有乱码,所以就想把它汉化.在网上搜索了一下,把步骤记录如下: 首先到这个网站去 http://aptana.com/support 选择View Docu ...
- html简单的分享功能
超级简单的分享. 包括:QQ.QQ空间.新浪微博.腾讯微博,微信(只是一个二维码): 1.首先是html代码: (前端我并不太会,一直用的都是bootstrap) <div class=&quo ...