题意:给定上一棵树,然后每条边有一个权值,然后每个点到 1 的距离有两种,第一种是直接回到1,花费是 dist(1, i)^2,还有另一种是先到另一个点 j,然后两从 j 向1走,当然 j 也可以再向 k,一直到1,但经过一个点,那么就会出多一个花费 p,问你每个点到 1 的最小距离的最大值是多少。

题解:dp【i】代表从1节点出发,向下传递到i节点的最小花费,dp[i]=min(dp[j]+dis[i]-dis[j])^2,j是从i到1链上的每一个点,很明显的斜率优化,dis[i]是i到根节点的距离

dp[i]+2*dis[i]dis[j]= dis[j]+dis[i]*dis[i]+dis[j]*dis[j];

b  +   k      *  x  =   y

需要注意的 是在dfs的时候要记录一下上一层的head和last和q[last+1],因为改变的只有最后覆盖的last+1,方便退回到原来的状态

//#pragma comment(linker, "/stack:200000000")
//#pragma GCC optimize("Ofast,no-stack-protector")
//#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
//#pragma GCC optimize("unroll-loops")
#include<bits/stdc++.h>
#define fi first
#define se second
#define mp make_pair
#define pb push_back
#define pi acos(-1.0)
#define ll long long
#define vi vector<int>
#define mod 1000000007
#define C 0.5772156649
#define ls l,m,rt<<1
#define rs m+1,r,rt<<1|1
#define pil pair<int,ll>
#define pli pair<ll,int>
#define pii pair<int,int>
#define cd complex<double>
#define ull unsigned long long
#define base 1000000000000000000
#define fio ios::sync_with_stdio(false);cin.tie(0) using namespace std; const double g=10.0,eps=1e-;
const int N=+,maxn=+,inf=0x3f3f3f3f,INF=0x3f3f3f3f3f3f3f3f; vector<pair<int,ll> >v[N];
ll dis[N],dp[N],ans,P;
int q[N],head,last;
struct node{
int head,last;
int id,change;
}p[N];
inline ll x(int j)
{
return dis[j];
}
inline ll y(int j)
{
return dp[j]+dis[j]*dis[j];
}
inline double slope(int i,int j)
{
// printf("------%d %d\n", i, j);
return (y(i)-y(j))/(x(i)-x(j));
}
void dfsdis(int u,int f,ll val)
{
dis[u]=val;
for(int i=;i<v[u].size();i++)
{
int x=v[u][i].fi;
if(x!=f)dfsdis(x,u,val+v[u][i].se);
}
// printf("%d %d\n",u,dis[u]);
}
void dfs(int u,int f)
{
for(int i=;i<v[u].size();i++)
{
int x=v[u][i].fi;
if(x!=f)
{
// for(int j=head;j<=last;j++)printf("%d ",q[j]);printf("%d\n",x);
p[x].head=head,p[x].last=last;
while(head<last&&slope(q[head],q[head+])<*dis[x])head++;
int te=q[head];
dp[x]=dp[te]+(dis[x]-dis[te])*(dis[x]-dis[te])+P;
// printf("%lld %d %lld\n",P,x,dp[x]);
ans=max(ans,dp[x]);
while(head<last&&slope(q[last-],q[last])>slope(q[last],x))last--;
p[x].id=last+,p[x].change=q[last+];
q[++last]=x;
dfs(x,u);
head=p[x].head,last=p[x].last;
q[p[x].id]=p[x].change;
// for(int j=head;j<=last;j++)printf("%d ",q[j]);printf("%d\n",x);
}
}
}
int main()
{
int T;scanf("%d",&T);
while(T--)
{
int n;
scanf("%d%d",&n,&P);
for(int i=;i<=n;i++)v[i].clear();
for(int i=;i<n;i++)
{
int u,vv;ll w;
scanf("%d%d%lld",&u,&vv,&w);
v[u].pb(mp(vv,w));
v[vv].pb(mp(u,w));
}
dfsdis(,-,);
head=,last=;q[head]=;dp[]=-P;
ans=;
dfs(,-);
printf("%lld\n",ans);
}
return ;
}
/***********************
3
6 10
1 2 4
2 3 5
1 4 3
4 5 3
5 6 3
***********************/

HDU - 59562016ACM/ICPC亚洲区沈阳站I - The Elder 树上斜率优化dp的更多相关文章

  1. HDU 5950 Recursive sequence 【递推+矩阵快速幂】 (2016ACM/ICPC亚洲区沈阳站)

    Recursive sequence Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Other ...

  2. HDU 5952 Counting Cliques 【DFS+剪枝】 (2016ACM/ICPC亚洲区沈阳站)

    Counting Cliques Time Limit: 8000/4000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) ...

  3. HDU 5948 Thickest Burger 【模拟】 (2016ACM/ICPC亚洲区沈阳站)

    Thickest Burger Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)T ...

  4. HDU 5949 Relative atomic mass 【模拟】 (2016ACM/ICPC亚洲区沈阳站)

    Relative atomic mass Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Oth ...

  5. HDU 6227.Rabbits-规律 (2017ACM/ICPC亚洲区沈阳站-重现赛(感谢东北大学))

    Rabbits Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 262144/262144 K (Java/Others)Total S ...

  6. HDU 6225.Little Boxes-大数加法 (2017ACM/ICPC亚洲区沈阳站-重现赛(感谢东北大学))

    整理代码... Little Boxes Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 262144/262144 K (Java/O ...

  7. 2015ACM/ICPC亚洲区沈阳站 Pagodas

    Pagodas Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Total Sub ...

  8. 2015ACM/ICPC亚洲区沈阳站 B-Bazinga

    Bazinga Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Total Sub ...

  9. 2016ACM/ICPC亚洲区沈阳站-重现赛赛题

    今天做的沈阳站重现赛,自己还是太水,只做出两道签到题,另外两道看懂题意了,但是也没能做出来. 1. Thickest Burger Time Limit: 2000/1000 MS (Java/Oth ...

随机推荐

  1. JVM之参数分配详解

    开篇之前,推荐一个关于JVM很不错的博客:http://www.cnblogs.com/redcreen/archive/2011/05/04/2036387.html 一.堆参数设置 -XX:+Pr ...

  2. Java中二叉树存储结构实现

    一.二叉树 二叉树指的是每个节点最多只能有两个子树的有序树.通常左边的子树被称为“左子树”(left subtree),右边的子树被称为右子树. 二叉树的每个节点最多只有2棵子树,二叉树的子树次序不能 ...

  3. Linux环境下Netstat与PS的使用

    Linux下用netstat查看网络状态.端口状态 在linux一般使用netstat 来查看系统端口使用情况步. netstat命令是一个监控TCP/IP网络的非常有用的工具,它可以显示路由表.实际 ...

  4. MapReduce Unit Test

    以前用java写MR程序总不习惯写单元测试,就是查错也只是在小规模数据上跑一下程序.昨天工作时,遇到一个bug,查了好久也查出来.估计是业务逻辑上的错误.后来没办法,只好写了个单元测试,一步步跟踪,瞬 ...

  5. Java-线程池专题(什么是线程池,如何使用,为什么要用)

    1.什么是线程池:  java.util.concurrent.Executors提供了一个 java.util.concurrent.Executor接口的实现用于创建线程池 多线程技术主要解决处理 ...

  6. Docker-docker制作镜像

    一.下载镜像 a.以daocloud为mirror下载Nginx镜像 配置daocloud为mirror,下载Nginx镜像:(daocloud官网登陆后,发现镜像里找到Nginx镜像) 下载Ngin ...

  7. windows忘记密码

    方法一 在开机时,按下F8进入”带命令提示符的安全”模式 输入”NET USER+用户名+123456/ADD”可把某用户的密码强行设置为”123456″ 方法二 如用户忘记登入密码可按下列方法解决 ...

  8. ora-12154:tns:could not resolve the connect identifier specied

    今天在发布网站时,点击登录之后出现了这个问题,修改一下环境变量,该问题就顺利解决了,解决方法如下: 在环境变量里,找到[Administrator的用户变量(U)],在其之下新建一个用户变量: 变量名 ...

  9. @Override笔记

    作用:用来保证正确重写方法,当你重写方法出错时,比如方法名误写,或者漏掉参数,编译器会提示编译错误. 使用场景:继承父类,重写父类方法:实现接口,实现接口方法. 备注:jdk1.5之允许在继承时使用, ...

  10. 20145335郝昊《java程序设计》第7周学习总结

    20145335郝昊 <Java程序设计>第7周学习总结 教材学习内容总结 认识时间与日期 格林威治标准时间:简称GMT时间,参考格林威治皇家天文台的标准太阳时间. 世界时:简称UT,借由 ...