举个例子来理解

16年沈阳区域赛【树形dp+斜率优化】

题意:

给你n个点,n-1条边的树。每条边有一个权值w。给你一个值p。

1号节点为根节点。求1号点到所有节点的路径中的最小权值  的最大值。

权值计算方法:将这条路可以一次走完,权值是(dis[u]-dis[1])*(dis[u]-dis[1]),也可以分段走完,每经过一个点权值加p,假如经过一个点x,那么权值可以是(dis[u]-dis[x])*(dis[u]-dis[x])+p+(dis[x]-dis1])*(dis[x]-dis1])

如果一个一个找分段的点就是O(N^2),那么可以用斜率优化的方法

终点是u,如果v点比w点作为暂停的点更优,那么dp[i]是到达i的的最小的权值

dp[v]+p+(dis[u]-dis[v])*(dis[u]-dis[v])<=dp[w]+p+(dis[u]-dis[w])*(dis[u]-dis[w]);

dp[v]+dis[u]^2+dis[v]^2-2*dis[u]*dis[v]<=dp[w]+dis[u]^2+dis[w]^2-2*dis[u]*dis[w];

dp[v]+dis[v]^2-2*dis[u]*dis[v]<=dp[w]+dis[w]^2-2*dis[u]*dis[w];

dp[v]+dis[v]^2-dp[w]-dis[w]^2<=2*dis[u]*(dis[v]-dis[w]);

不妨假设f[x]=dp[x]+dis[x]^2;

那么 f[v]-f[w]<=2*dis[u]*(dis[v]-dis[w]);

假设某点是(dis[x],f[x]),那么就是斜率问题了,当且仅当v>w且时v点更新u,比w点更新w优。

这时候就需要维护凸包了:

维护凸包(下凸)原因:

假设存在这样的三个点

,很明显他们存在这样的关系

那么他们跟2*dis[u]会存在三种可能的关系:

1.,此时i比j优,j比k优

2.此时i比j优,k比j优

3.此时j比i优,k比j优

综上所述j不会是最优,所以要维护一个凸包(下凸)。

假如

每次在得到一个新的状态的时候,由于dis[]的单调性,它的位置必然是在这个半凸壳的右端处。由于dis[]的单调性,f[]也是满足单调递增,这样就可以用一个单调队列来维护半凸壳上的点。

队头的维护:(当l和(l+1)斜率小于2*dis[u],删掉l,因为(l+1)更优)

while(l<r&&gety(q[l+1],q[l])<=2*dis[u]*getx(q[l+1],q[l])) l++;

队尾维护:(维护斜率的增长,此时这三个点从左到右(r-1),r,u,如果不是单调递增的,r不会是优的,所以删掉)

    while(l<r&&getx(u,q[r])*gety(q[r],q[r-1])>=gety(u,q[r])*getx(q[r],q[r-1])) r--;

1. 检查队头的两个元素q[l]和q[l+1],通过上面的斜率检查,如果q[l+1]比q[l]更优,那么就把q[l]出队。

2. 直接取队头的元素为目标状态,进行状态转移,计算出f[u]。

3. 将u插入队尾。插入之前需要检查三个状态q[r-1], q[r], u是否满足斜率单调递增,若不满足则将q[r]出队。

需要注意的是,由于每个节点可能有多个子节点,因此每次转移之后要将队尾恢复为原来的元素。

代码:

#include<bits/stdc++.h>
#define ll long long
#define inf 0x3f3f3f3f3f3f3f3fLL
using namespace std;
const int maxn=200010;
int n,m,k,x,y,s;
ll ans,tmp,cnt,p,aa;
ll zt[maxn],l,r;
struct node
{int to,nex;ll w;
}a[maxn];
int he[maxn],tot,q[maxn];
ll dp[maxn],dis[maxn];
void add(int u,int v,ll w)
{a[tot].to=v;a[tot].w=w;a[tot].nex=he[u];he[u]=tot++;
}
void init()
{tot=r=0;l=1;memset(he,-1,sizeof(he));memset(dis,0,sizeof(dis));ans=0;dp[1]=q[0]=0;
}
ll gety(int u,int v)
{return dp[u]+dis[u]*dis[u]-dp[v]-dis[v]*dis[v];
}
ll getx(int u,int v){return dis[u]-dis[v];}
ll getdp(int u,int v){return dp[v]+p+(dis[u]-dis[v])*(dis[u]-dis[v]);}void getpre(int u,int fa)
{for(int i=he[u];i!=-1;i=a[i].nex){int v=a[i].to;if(v==fa) continue;dis[v]=dis[u]+a[i].w;// cout<<v<<" "<<dis[v]<<endl;getpre(v,u);}
}
void dfs(int u,int fa,int l,int r)
{int pre=-1;while(l<r&&gety(q[l+1],q[l])<=2*dis[u]*getx(q[l+1],q[l])) l++;//cout<<dp[u]<<endl;dp[u]=min(dp[u],getdp(u,q[l]));while(l<r&&getx(u,q[r])*gety(q[r],q[r-1])>=gety(u,q[r])*getx(q[r],q[r-1])) r--;pre=q[++r];q[r]=u;ans=max(ans,dp[u]);for(int i=he[u];i!=-1;i=a[i].nex){int v=a[i].to;if(v==fa) continue;dfs(v,u,l,r);}if(pre!=-1) q[r]=pre;//恢复队尾
}
int main()
{int T,cas=1;scanf("%d",&T);while(T--){scanf("%d%lld",&n,&p);init();for(int i=0;i<n-1;i++){scanf("%d%d%lld",&x,&y,&aa);add(x,y,aa);add(y,x,aa);}getpre(1,-1);for(int i=1;i<=n;i++)dp[i]=dis[i]*dis[i];dfs(1,-1,1,0);printf("%lld\n",ans);//  if(flag) puts("Yes"); else puts("No");}return 0;
}

斜率优化理解【16年 沈阳区域赛 The Elder 】相关推荐

  1. 2021ICPC沈阳区域赛BEFIJM

    2021ICPC沈阳区域赛BEFIJM E. Edward Gaming, the Champion 题意 给定长度不超过2e52\mathrm{e}52e5的文本串,统计其中"edgnb& ...

  2. icpc 2020沈阳区域赛补题

    2020沈阳区域赛 H 这题是一道典型dp 但是需要用滚动数组优化空间, 在状态转移的时候需要考虑一下是否满足天数条件. 我真的吐了,debug改了半天之后发现错误原因是: 排序应该是 sort(v+ ...

  3. 2017 ICPC沈阳区域赛

    2017 沈阳区域赛 题号 题目 难度 知识点 A BBP Formula B Bridge C Empty Convex Polygons D Defense of the Ancients E F ...

  4. 记2015沈阳区域赛

    前记 基本确定了要去沈阳和上海打区域赛,听说苏大cp也会沈阳,于是我们的最终目标变为了压苏大. 周五 下午一点左右的飞机,本来想要早上赶概率论作业然后交到学校去,结果睡晚了,干脆就早点去了机场,然后大 ...

  5. 退役了,总结的ACM近年区域赛的所有题型

    前面的是退役小记,后面是我个人写近2年所有区域赛场次记录的题型(请忽略我记录的感受),可以留着看下最近的场次名称和原题在哪里有 目录 退役小记(没兴趣可以不看) 这里简单记下我的acm生涯 省赛和三场 ...

  6. bzoj1560:[JSOI2009]火星藏宝图(斜率优化)

    题目描述 在火星游玩多日,jyy偶然地发现了一张藏宝图.根据藏宝图上说法,宝藏被埋藏在一个巨大的湖里的N个岛上(2<=N<=200,000).为了方便描述,地图把整个湖划分成M行M列(1& ...

  7. 2013长春区域赛总结

    今年因为参加了一场日本的区域赛,国内的区域赛只有一次机会.选择了来最后一个赛区长春,一方面准备时间比较充裕,另一方面也想弥补上年在长春留下的遗憾.长春是我的最后一场区域赛了,本来想着拿个金牌退役的,万 ...

  8. bzoj3156 防御准备 - 斜率优化

    Input 第一行为一个整数N表示战线的总长度. 第二行N个整数,第i个整数表示在位置i放置守卫塔的花费Ai. Output 共一个整数,表示最小的战线花费值. Sample Input 10 2 3 ...

  9. 【bzoj1010】玩具装箱toy——斜率优化dp

    题目链接 第一道自己推的斜率优化dp>< 首先要明确一点:装进同一个容器的toys一定要是连着的几个(否则的话可以直接贪心)-->之前理解错题意WA了一次...... 用sum[i] ...

  10. BZOJ3437:小P的牧场(斜率优化DP)

    Description 小P在MC里有n个牧场,自西向东呈一字形排列(自西向东用1-n编号),于是他就烦恼了:为了控制这n个牧场,他需要在某些牧场上面建立控制站,每个牧场上只能建立一个控制站,每个控制 ...

最新文章

  1. 诺奖得主克鲁格曼:比特币是庞氏骗局,但不一定很快走向崩溃
  2. 腾讯开源项目盘点:WeUI,WePY,Tinker,Mars等
  3. MVC 用户权限HttpContext.User.IsInRole()
  4. TypeScript里的中括号类型定义法
  5. 真正的大学老师,是那些无需打卡和考评,也会不可遏止地要去读书写作和上课的人...
  6. plsql数据库异常---plsql 登录后,提示数据库字符集(AL32UTF8)和客户端字符集(ZHS16GBK)不一致 .
  7. 人工智能 - paddlepaddle飞桨 - 深度学习基础教程 - 编程指南
  8. html表格td的内容修改,点击table中的td,修改td中的内容功能实现
  9. 初识Linux操作系统
  10. 穷人变富的过程中,最大的阻碍是什么?
  11. Ubuntu16.04.1安装Caffe(GPU)
  12. xampp mysql关机意外_xampp运行MySQL shutdown unexpectedly解决方法
  13. 计算机控制手机源码,Total Control电脑控制手机助手
  14. mac的鼠标滚动方向和触摸板方向,一个插件搞定
  15. sql注入开源网站包
  16. java 打印 边距_缩小边距 – Java打印
  17. JavaScript中throw的错误异常处理
  18. 蕉下招股书里提了26次的DTC,到底是啥?
  19. 机器学习小组知识点4:批量梯度下降法(BGD)
  20. 安卓开发之视频播放器

热门文章

  1. 神舟Z7-KP7SC笔记本电脑-游戏实机帧数截图与鲁大师跑分
  2. 有关win10的C:/ProgramFiles\WindowsApps\文件系统错误(12007)问题
  3. Windows与嵌入式linux设备数据传送工具——tftpd32软件使用说明
  4. 01_Snaker简介
  5. 消除无法用内置管理账户打开sticky notes
  6. onnx-modifier:ONNX可视化编辑
  7. migration php,Lavarel常用语句之Migration
  8. Java命令行开关_java命令行操作
  9. eclipse/Myeclipse注释模板修改
  10. XMLHttpRequest 状态码:readyState、status