分析:(官方题解)

首先考虑暴力,显然可以直接每次O(n^2)

​的连边,最后跑一次分层图最短路就行了.

然后我们考虑优化一下这个连边的过程 ,因为都是区间上的操作,所以能够很明显的想到利用线段树来维护整个图,

连边时候找到对应区间,把线段树的节点之间连边.这样可以大大缩减边的规模,然后再跑分层图最短路就可以了.

但是这样建图,每一次加边都要在O(logn)个线段树节点上加边,虽然跑的非常快,但是复杂度仍然是不科学的.

为了解决边的规模的问题,开两棵线段树,连边时候可以新建一个中间节点,在对应区间的节点和中间节点之间连边

进一步缩减了边的规模,强行下降一个数量级

最后跑一下分层图最短路就行了

复杂度O(mlog^2n)

什么你会线段树但是不会分层图最短路?安利JLOI2011飞行路线.

因为边的数目还是相对比较多的,所以不能使用SPFA,而要使用Heap-Dijkstra来做最短路,

但是不排除某些厉害的选手有特殊的SPFA姿势可以做或者普通 SPFA写的比较优美就不小心跑过去了...

注:出题人的题解写的很详细了,然后JLOI2011飞行路线是BZOJ2763 直接去做就好了

然后我的建图刚开始不太完善,跑了600+ms,然后后来完善了一下,按线段树节点建图(这就是题解)

不过每个线段树的节点不需要和它的区域内所有的点连边,只需要按照线段树的结构,连它的左右儿子就行了

代码:

#include <stdio.h>
#include <iostream>
#include <algorithm>
#include <vector>
#include <queue>
#include <string.h>
using namespace std;
typedef long long LL;
const int INF=0x3f3f3f3f;
const int N=5e4+;
int d[][N*+],head[N*+],tot,n,m,k;
struct Edge{
int v,w,next;
};
vector<Edge>edge;
void add(int u,int v,int w){
edge.push_back(Edge{v,w,head[u]});
head[u]=edge.size()-;
}
struct Node{
int cur,v,dis;
bool operator<(const Node &rhs)const{
return dis>rhs.dis;
}
};
priority_queue<Node>q;
bool vis[][N*+];
int dij(){
memset(d,INF,sizeof(d));
memset(vis,,sizeof(vis));
d[][*N+]=;
q.push(Node{,*N+,});
while(!q.empty()){
int cur=q.top().cur,u=q.top().v;
q.pop();
if(vis[cur][u])continue;
vis[cur][u]=;
for(int i=head[u];~i;i=edge[i].next){
int v=edge[i].v;
if(!vis[cur][v]&&d[cur][v]>d[cur][u]+edge[i].w){
d[cur][v]=d[cur][u]+edge[i].w;
q.push(Node{cur,v,d[cur][v]});
}
if(cur+>k)continue;
if(!vis[cur+][v]&&d[cur+][v]>d[cur][u]){
d[cur+][v]=d[cur][u];
q.push(Node{cur+,v,d[cur+][v]});
}
}
}
return d[k][*N+n]==INF?-:d[k][*N+n];
}
void build(int rt,int l,int r){
if(l==r){
add(N*+l,rt,);
add(rt+*N,N*+l,);
return;
}
int mid=(l+r)>>;
build(rt<<,l,mid);
build(rt<<|,mid+,r);
add(rt<<,rt,),add(rt<<|,rt,);
add(rt+*N,*N+rt*,),add(rt+*N,*N+rt*+,);
}
int now,w;
void treeadd1(int rt,int l,int r,int x,int y){
if(x<=l&&r<=y){
add(rt,now,w);
return;
}
int mid=(l+r)>>;
if(x<=mid)treeadd1(rt<<,l,mid,x,y);
if(y>mid)treeadd1(rt<<|,mid+,r,x,y);
}
void treeadd2(int rt,int l,int r,int x,int y){
if(x<=l&&r<=y){
add(now,rt+*N,);
return;
}
int mid=(l+r)>>;
if(x<=mid)treeadd2(rt<<,l,mid,x,y);
if(y>mid)treeadd2(rt<<|,mid+,r,x,y);
}
int main(){
scanf("%d%d%d%d",&n,&n,&m,&k);
memset(head,-,sizeof(head));
edge.clear();
build(,,n);
now=*N;
for(int i=;i<=m;++i){
int a,b,c,d;
scanf("%d%d%d%d%d",&a,&b,&c,&d,&w);
++now;
treeadd1(,,n,a,b);
treeadd2(,,n,c,d);
++now;
treeadd1(,,n,c,d);
treeadd2(,,n,a,b);
}
int ans=dij();
if(ans==-)printf("CreationAugust is a sb!\n");
else printf("%d\n",ans);
return ;
}

HDU5669 Road 分层最短路+线段树建图的更多相关文章

  1. BZOJ4383/LuoGuP3588 Pustynia/PUS 线段树建图优化

    我会告诉你我看了很久很久才把题目看懂吗???怀疑智商了 原来他给的l,r还有k个数字都是下标... 比如给了一个样例 l, r, k, x1,x2,x3...xk,代表的是一个数组num[l]~num ...

  2. Codeforces Round #406 (Div. 1) B. Legacy 线段树建图跑最短路

    B. Legacy 题目连接: http://codeforces.com/contest/786/problem/B Description Rick and his co-workers have ...

  3. 【转】Codeforces Round #406 (Div. 1) B. Legacy 线段树建图&&最短路

    B. Legacy 题目连接: http://codeforces.com/contest/786/problem/B Description Rick and his co-workers have ...

  4. Codeforces Round #406 (Div. 2) D. Legacy (线段树建图dij)

    D. Legacy time limit per test 2 seconds memory limit per test 256 megabytes input standard input out ...

  5. POJ 2374 线段树建图+Dijkstra

    题意: 思路: 线段树+Dijkstra(要堆优化的) 线段树要支持打标记 一个栅栏 拆成两个点 :左和右 新加一个栅栏的时候 看看左端点有没有被覆盖过 如果有的话 就分别从覆盖的那条线段的左右向当前 ...

  6. BZOJ3073 [Pa2011]Journeys[最短路—线段树优化建边]

    新技能get✔. 线段树优化建边主要是针对一类连续区间和连续区间之间建边的题,建边非常的优秀.. 这题中,每次要求$[l1,r1]$每一点向$[l2,r2]$每一点建无向边,然后单元最短路. 暴力建边 ...

  7. CF-787D-线段树建图+最短路

    http://codeforces.com/problemset/problem/787/D 题目大意是给出一个有向图,有N个节点,初始节点在S,询问S到所有点最短路.边的读入方式有三种, 1 u v ...

  8. [BZOJ4699]树上的最短路(最短路+线段树)

    https://www.cnblogs.com/Gloid/p/10273902.html 这篇文章已经从头到尾讲的非常清楚了,几乎没有什么需要补充的内容. 首先$O(n\log^2 n)$的做法比较 ...

  9. [TJOI2012]桥(最短路+线段树)

    有n个岛屿, m座桥,每座桥连通两座岛屿,桥上会有一些敌人,玩家只有消灭了桥上的敌人才能通过,与此同时桥上的敌人会对玩家造成一定伤害.而且会有一个大Boss镇守一座桥,以玩家目前的能力,是不可能通过的 ...

随机推荐

  1. Windows Linux HackMacintosh

    我想把Windows Linux HackMacintosh三类系统融入到一台笔记本上的神经病应该不多. 我的电脑就一个SATA硬盘,BIOS还不是EFI的.一共同时安装了Windows 8.1.Op ...

  2. MySQL基础学习之视图

    创建新的视图 CREATE VIEW 视图名  AS SELECT  属性,属性1,属性2  FROM 表名 创建新的视图并指定数据名 CREATE VIEW 视图名(新属性,新属性1,新属性2)   ...

  3. JAVA获取当前日期以及将字符串转成指定格式的日期

    /* * To change this template, choose Tools | Templates * and open the template in the editor. */ pac ...

  4. STL容器的本质

    http://blog.sina.com.cn/s/blog_4d3a41f40100eof0.html 最近在学习unordered_map里面的散列函数和相等函数怎么写.学习过程中看到了一个好帖子 ...

  5. merge into 和 update 的效率对比

    以前只考虑 merge into 只是在特定场合下方便才使用的,今天才发现,merge into 竟然会比 update 在更新数据时有这么大的改进.其实呢,merge into部分的update和u ...

  6. MVC-内容详情页显示内容

    @model InfoDataProvider.DataModel.FAQ_ContentUser 内容Content字段:如果里面有html标签. @Html.DisplayFor(p => ...

  7. IDEA的使用

    1.设置字体file->setting->color$fonts->font 保存提示设置file->Settings -> Editor -> General - ...

  8. JQ实现3D拖拽效果

    <!DOCTYPE HTML> <html onselectstart='return false'> <head> <meta http-equiv=&qu ...

  9. Python属性、方法和类管理系列之----元类

    元类的介绍 请看位于下面网址的一篇文章,写的相当好. http://blog.jobbole.com/21351/ 实例补充 class Meta(type): def __new__(meta, c ...

  10. 使用Yeoman搭建 AngularJS 应用 (1) —— 介绍

    原文地址:http://yeoman.io/learning/ Yeoman 是一个通用的可以创建多种应用的基架系统.它帮助用户快速搭建新的项目,并且可以简化已存在项目的维护过程. Yeoman是不限 ...