HDU5669 Road 分层最短路+线段树建图
分析:(官方题解)
首先考虑暴力,显然可以直接每次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 分层最短路+线段树建图的更多相关文章
- BZOJ4383/LuoGuP3588 Pustynia/PUS 线段树建图优化
我会告诉你我看了很久很久才把题目看懂吗???怀疑智商了 原来他给的l,r还有k个数字都是下标... 比如给了一个样例 l, r, k, x1,x2,x3...xk,代表的是一个数组num[l]~num ...
- Codeforces Round #406 (Div. 1) B. Legacy 线段树建图跑最短路
B. Legacy 题目连接: http://codeforces.com/contest/786/problem/B Description Rick and his co-workers have ...
- 【转】Codeforces Round #406 (Div. 1) B. Legacy 线段树建图&&最短路
B. Legacy 题目连接: http://codeforces.com/contest/786/problem/B Description Rick and his co-workers have ...
- 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 ...
- POJ 2374 线段树建图+Dijkstra
题意: 思路: 线段树+Dijkstra(要堆优化的) 线段树要支持打标记 一个栅栏 拆成两个点 :左和右 新加一个栅栏的时候 看看左端点有没有被覆盖过 如果有的话 就分别从覆盖的那条线段的左右向当前 ...
- BZOJ3073 [Pa2011]Journeys[最短路—线段树优化建边]
新技能get✔. 线段树优化建边主要是针对一类连续区间和连续区间之间建边的题,建边非常的优秀.. 这题中,每次要求$[l1,r1]$每一点向$[l2,r2]$每一点建无向边,然后单元最短路. 暴力建边 ...
- CF-787D-线段树建图+最短路
http://codeforces.com/problemset/problem/787/D 题目大意是给出一个有向图,有N个节点,初始节点在S,询问S到所有点最短路.边的读入方式有三种, 1 u v ...
- [BZOJ4699]树上的最短路(最短路+线段树)
https://www.cnblogs.com/Gloid/p/10273902.html 这篇文章已经从头到尾讲的非常清楚了,几乎没有什么需要补充的内容. 首先$O(n\log^2 n)$的做法比较 ...
- [TJOI2012]桥(最短路+线段树)
有n个岛屿, m座桥,每座桥连通两座岛屿,桥上会有一些敌人,玩家只有消灭了桥上的敌人才能通过,与此同时桥上的敌人会对玩家造成一定伤害.而且会有一个大Boss镇守一座桥,以玩家目前的能力,是不可能通过的 ...
随机推荐
- Windows Linux HackMacintosh
我想把Windows Linux HackMacintosh三类系统融入到一台笔记本上的神经病应该不多. 我的电脑就一个SATA硬盘,BIOS还不是EFI的.一共同时安装了Windows 8.1.Op ...
- MySQL基础学习之视图
创建新的视图 CREATE VIEW 视图名 AS SELECT 属性,属性1,属性2 FROM 表名 创建新的视图并指定数据名 CREATE VIEW 视图名(新属性,新属性1,新属性2) ...
- JAVA获取当前日期以及将字符串转成指定格式的日期
/* * To change this template, choose Tools | Templates * and open the template in the editor. */ pac ...
- STL容器的本质
http://blog.sina.com.cn/s/blog_4d3a41f40100eof0.html 最近在学习unordered_map里面的散列函数和相等函数怎么写.学习过程中看到了一个好帖子 ...
- merge into 和 update 的效率对比
以前只考虑 merge into 只是在特定场合下方便才使用的,今天才发现,merge into 竟然会比 update 在更新数据时有这么大的改进.其实呢,merge into部分的update和u ...
- MVC-内容详情页显示内容
@model InfoDataProvider.DataModel.FAQ_ContentUser 内容Content字段:如果里面有html标签. @Html.DisplayFor(p => ...
- IDEA的使用
1.设置字体file->setting->color$fonts->font 保存提示设置file->Settings -> Editor -> General - ...
- JQ实现3D拖拽效果
<!DOCTYPE HTML> <html onselectstart='return false'> <head> <meta http-equiv=&qu ...
- Python属性、方法和类管理系列之----元类
元类的介绍 请看位于下面网址的一篇文章,写的相当好. http://blog.jobbole.com/21351/ 实例补充 class Meta(type): def __new__(meta, c ...
- 使用Yeoman搭建 AngularJS 应用 (1) —— 介绍
原文地址:http://yeoman.io/learning/ Yeoman 是一个通用的可以创建多种应用的基架系统.它帮助用户快速搭建新的项目,并且可以简化已存在项目的维护过程. Yeoman是不限 ...