又是废掉的一个div2啊

第一次在学校熬夜打cf,开心还看到了自己最喜欢的斜率优化ohhh

链接 :E - Long Way Home

看到那个平方就可以靠感觉认为是斜率优化了....

感觉似不似有点想法??k只有20...

可以试着去考虑最后一步用飞机,然后跑dijkstra求出走普通路径的。

其实就这样了...


考虑k=1的情况:

在最后坐飞机,前面都普通路径行走

则:\(d_{new}[i]=min(d_{old}[j]+(i-j)^2)\)

\(d_{new}\)为最后的答案,就是在最后坐飞机,\(d_{old}\)就是前面已经处理的走普通路径

然后跑一遍dijkstra,看看是否会更新(即假设存在A->C的最短路径为:A->B最后坐飞机,B->C走普通路径)


处理k>1的情况也是一样的,做k次dp,每一次在dp后跑最短路看能否用普通路径更新。

注意的是在一开始要跑一遍最短路,代表坐0次飞机的最短路径。

然后就是对于这个dp式子的处理了:

观察发现可以把式子转换为:\(d_{old}[j]+j^2=2ij+d_{new}[i]-i^2\)

斜率为\(2i\),X为\(j\),Y为\(d_{old}[j]+j^2\)。斜率和X都单调递增,所以可以画图发现决策点是下凸(为什么不转换式子要画图?因为j有特殊的点)

这个j特殊的点就在于没有范围的限制,也就是范围是(1<=j<=n)

所以就不可以在循环中加入单调队列

可以先一遍循环把所有决策点存入单调队列,然后再一遍循环更新答案

就完了....

对了!还有一个点:因为m可能小于n,图可能不连通,也就是说从只1号点跑dijkstra就不一定可以遍历完,所以就需要在dp时如果更新了\(d_{new}\)就要把它放入优先队列中,以保证每个点都可以更新到。

Over.

一定要在计算Y的时候把\(j^2\)开成long long啊!!!麻了,改了一个小时(ku)

总的复杂度\(O(k(mlogn+n))\)

代码:

#include<bits/stdc++.h>
#define ll long long
using namespace std;
inline int read(){
register int x = 0, t = 1;
register char ch=getchar();
while(ch<'0'||ch>'9'){
if(ch=='-')
t=-1;
ch=getchar();
}
while(ch>='0'&&ch<='9'){
x=(x<<1)+(x<<3)+(ch^48);
ch=getchar();
}
return x*t;
}
struct node{
int to,nxt,w;
}e[200010];
int head[100010],cnt,vis[100010];
void add(int u,int v,int w){
e[++cnt].to=v;
e[cnt].nxt=head[u];
e[cnt].w=w;
head[u]=cnt;
}
ll dist[100010],dis[110000]/*old*/;
struct h{
int id;
ll dis;
bool operator<(const h &other)const{
return dis>other.dis;
}
};
priority_queue<h>qu;
void dijkstra(){//更新以普通边结尾
memset(vis,0,sizeof(vis));
qu.push((h){1,0});
while(!qu.empty()){
int p=qu.top().id;
qu.pop();
if(vis[p])continue;
vis[p]=1;
for(int i=head[p];i;i=e[i].nxt){
int v=e[i].to;
if(dist[v]>dist[p]+e[i].w){
dist[v]=dist[p]+e[i].w;
qu.push((h){v,dist[v]});
}
}
}
}
int q[100010],hd,tl;
ll Y(int i){return dis[i]+(ll)i*i;/*爆了!!*/}
ll X(int i){return i;}
ll K(int i){return 2*i;}
double slope(int x,int y){//x>y
if(X(x)==X(y)){
if(Y(x)<Y(y))return -1e18;
else return 1e18;
}
return (double)(Y(x)-Y(y))/(X(x)-X(y));
}
int main(){
int n=read(),m=read(),k=read();
for(int i=1;i<=m;i++){
int x=read(),y=read(),w=read();
add(x,y,w),add(y,x,w);
}
for(int i=2;i<=n;i++)dist[i]=1e18;
dijkstra();
while(k--){
for(int i=1;i<=n;i++)dis[i]=dist[i];
hd=tl=0;
for(int i=1;i<=n;i++){
//下凸壳
while(hd+1<tl&&slope(i,q[tl-1])<=slope(q[tl-1],q[tl-2]))tl--;
q[tl++]=i;
}
for(int i=1;i<=n;i++){
while(hd+1<tl&&slope(q[hd+1],q[hd])<=K(i))hd++;
if(hd<tl){
int j=q[hd];
if(dist[i]>dis[j]+(ll)(j-i)*(j-i)){
dist[i]=dis[j]+(ll)(j-i)*(j-i);
qu.push((h){i,dist[i]});
}
}
}
dijkstra();
}
for(int i=1;i<=n;i++)printf("%lld ",dist[i]);
return 0;
}

Codeforces 1715E - Long Way Home的更多相关文章

  1. python爬虫学习(5) —— 扒一下codeforces题面

    上一次我们拿学校的URP做了个小小的demo.... 其实我们还可以把每个学生的证件照爬下来做成一个证件照校花校草评比 另外也可以写一个物理实验自动选课... 但是出于多种原因,,还是绕开这些敏感话题 ...

  2. 【Codeforces 738D】Sea Battle(贪心)

    http://codeforces.com/contest/738/problem/D Galya is playing one-dimensional Sea Battle on a 1 × n g ...

  3. 【Codeforces 738C】Road to Cinema

    http://codeforces.com/contest/738/problem/C Vasya is currently at a car rental service, and he wants ...

  4. 【Codeforces 738A】Interview with Oleg

    http://codeforces.com/contest/738/problem/A Polycarp has interviewed Oleg and has written the interv ...

  5. CodeForces - 662A Gambling Nim

    http://codeforces.com/problemset/problem/662/A 题目大意: 给定n(n <= 500000)张卡片,每张卡片的两个面都写有数字,每个面都有0.5的概 ...

  6. CodeForces - 274B Zero Tree

    http://codeforces.com/problemset/problem/274/B 题目大意: 给定你一颗树,每个点上有权值. 现在你每次取出这颗树的一颗子树(即点集和边集均是原图的子集的连 ...

  7. CodeForces - 261B Maxim and Restaurant

    http://codeforces.com/problemset/problem/261/B 题目大意:给定n个数a1-an(n<=50,ai<=50),随机打乱后,记Si=a1+a2+a ...

  8. CodeForces - 696B Puzzles

    http://codeforces.com/problemset/problem/696/B 题目大意: 这是一颗有n个点的树,你从根开始游走,每当你第一次到达一个点时,把这个点的权记为(你已经到过不 ...

  9. CodeForces - 148D Bag of mice

    http://codeforces.com/problemset/problem/148/D 题目大意: 原来袋子里有w只白鼠和b只黑鼠 龙和王妃轮流从袋子里抓老鼠.谁先抓到白色老鼠谁就赢. 王妃每次 ...

随机推荐

  1. SpringBoot Restful 接口实现

    目录 SpringBoot 核心注解 SpringBoot Restful 接口实现 封装响应数据 SpringBoot 核心注解 SpringBoot 基础入门 注解 说明 Component 声明 ...

  2. AT32F415 修改时钟和晶振方法(原创)

    1. 简介 我们几乎是国内第一批使用AT32F415芯片的客户,那个时候芯片还没涨价,岁月一切静好.使用AT32F415 做了几个小产品,也在持续出货.后来大家都知道,涨价缺货愈演愈烈.好在我们提前囤 ...

  3. net core天马行空系列-微服务篇:全声明式http客户端feign快速接入微服务中心nacos

    1.前言 hi,大家好,我是三合,距离上一篇博客已经过去了整整两年,这两年里,博主通关了<人生>这个游戏里的两大关卡,买房和结婚.最近闲了下来,那么当然要继续写博客了,今天这篇博客的主要内 ...

  4. 基于.NetCore开发博客项目 StarBlog - (11) 实现访问统计

    系列文章 基于.NetCore开发博客项目 StarBlog - (1) 为什么需要自己写一个博客? 基于.NetCore开发博客项目 StarBlog - (2) 环境准备和创建项目 基于.NetC ...

  5. Python装饰器Decorators

    def hi(name="yasoob"): return "hi " + name print(hi()) # 我们甚至可以将一个函数赋值给一个变量,比如 g ...

  6. PyTorch DataLoader NumberWorkers Deep Learning Speed Limit Increase

    这意味着训练过程将按顺序在主流程中工作. 即:run.num_workers.   ,此外, ,因此,主进程不需要从磁盘读取数据:相反,这些数据已经在内存中准备好了. 这个例子中,我们看到了20%的加 ...

  7. Java 基础常见知识点&面试题总结(中),2022 最新版!| JavaGuide

    你好,我是 Guide.秋招即将到来,我对 JavaGuide 的内容进行了重构完善,公众号同步一下最新更新,希望能够帮助你. 上篇:Java 基础常见知识点&面试题总结(上),2022 最新 ...

  8. JAVA用for循环打印*三角形

    public class Sanjiaoxing { //本节为for循环的嵌套结构练习 public static void main(String[] args) { // TODO Auto-g ...

  9. SAP BPC 开发日记

    1.获取维度模型的方法1 DATA:i_appset_id TYPE uj_appset_id,     i_appl_id   TYPE uj_appl_id.i_appset_id = 'SINO ...

  10. 使用Thread类和Runnable接口实现多线程的区别

    使用Thread类和Runnable接口实现多线程的区别 先看两种实现方式的步骤: public class ThreadDemo{ public static void main(String[] ...