bzoj 3073: [Pa2011]Journeys -- 线段树优化最短路
3073: [Pa2011]Journeys
Time Limit: 20 Sec Memory Limit: 512 MB
Description
Input
Output
Sample Input
1 2 4 5
5 5 4 4
1 1 3 3
Sample Output
1
2
0
1
HINT
我们发现本题点数非常多,需要建的边也非常多,如果直接建图的话一定会TLE+MLE
但是我们会发现本题有一个很好的性质,就是连续一段区间都可以到达另外连续一段区间
如何优化这样连续的区间,我们就会想到一种数据结构——线段树
我们可以将线段树一段区间映射到这里,这样就可以用线段树上的几段完整表示整个区间,这也可以看成将点打包的思想
接下来我们考虑如何从【a,b】到【c,d】连边
首先,如果我们还是直接将每段线段连边的话它的复杂度还是很高
所以我们考虑抽象成新建两个点P1,P2,表示两段区间,这样从【a,b】到【c,d】,就是相当于从P1到P2连一条边
然后我们只要所有线段【a,b】向P1连边,P2向所有线段【c,d】连边就可以做到了
但是,这里还存在一个问题,就是如果把图建到一棵线段树中就会出现线段重叠,就会出问题
所以我们需要建两棵线段树A,B,表示从A会经过一条P边到B,这样就可以表示经过了一条边
然后我们对于A线段树中的点从儿子向父亲连一条权值为0的边(因为它本身属于这个集合,不需要代价)
从B线段树中的爹向儿子连一条权值为0的边(因为能到爹一定也能到儿子,不需要代价)
再从B中的叶子节点向A中对应叶子节点连一条权值为0的边(走完一条路径,到达对应点,继续从它开始出发)
这样,我们就可以跑最短路了
#include<map>
#include<cmath>
#include<queue>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
#define inf 1000000007
#define ll long long
#define M 4000010
#define N 500010
inline int rd()
{
int x=,f=;char ch=getchar();
while(ch<''||ch>''){if(ch=='-')f=-;ch=getchar();}
while(ch>=''&&ch<=''){x=x*+ch-'';ch=getchar();}
return x*f;
}
int n,m,p;
int lj[M],to[M<<],v[M<<],fro[M<<],cnt,ls[N<<],rs[N<<],ra,rb,tot,val[N],dis[M];
inline int add(int a,int b,int c){fro[++cnt]=lj[a];to[cnt]=b;v[cnt]=c;lj[a]=cnt;}
void build(int l,int r,int &x,int op)
{
x=++tot;
if(l==r){if(op) val[l]=x;return;}
int mid=l+r>>;
build(l,mid,ls[x],op);build(mid+,r,rs[x],op);
if(op) add(ls[x],x,),add(rs[x],x,);
else add(x,ls[x],),add(x,rs[x],);
}
void fadd(int l,int r,int x,int y)
{
if(l==r){add(y,x,);return;}
int mid=l+r>>;
fadd(l,mid,ls[x],ls[y]);fadd(mid+,r,rs[x],rs[y]);
}
void padd(int l,int r,int p,int L,int R,int x,int op)
{
if(L==l&&R==r)
{
if(op) add(x,p,);
else add(p,x,);
return;
}
int mid=l+r>>;
if(L>mid) padd(mid+,r,p,L,R,rs[x],op);
else if(R<=mid) padd(l,mid,p,L,R,ls[x],op);
else
{
padd(l,mid,p,L,mid,ls[x],op);
padd(mid+,r,p,mid+,R,rs[x],op);
}
}
void link(int a,int b,int c,int d)
{
padd(,n,++tot,a,b,ra,);add(tot,tot+,);
padd(,n,++tot,c,d,rb,);
}
#define pa pair<int,int>
priority_queue<pa,vector<pa >,greater<pa > >q;
bool vs[M];
void dij()
{
memset(dis,0x3f,sizeof(dis));
int l=,r=,x;
dis[val[p]]=;
q.push(make_pair(,val[p]));
while(!q.empty())
{
x=q.top().second;q.pop();
if(vs[x]) continue;vs[x]=;
for(int i=lj[x];i;i=fro[i])
if(dis[to[i]]>dis[x]+v[i])
{
dis[to[i]]=dis[x]+v[i];
q.push(make_pair(dis[to[i]],to[i]));
}
}
}
int main()
{
int a,b,c,d;
n=rd();m=rd();p=rd();
build(,n,ra,);build(,n,rb,);fadd(,n,ra,rb);
for(int i=;i<=m;i++)
{
a=rd();b=rd();c=rd();d=rd();
link(a,b,c,d);link(c,d,a,b);
}
dij();
for(int i=;i<=n;i++) printf("%d\n",dis[val[i]]);
return ;
}
bzoj 3073: [Pa2011]Journeys -- 线段树优化最短路的更多相关文章
- bzoj 3073 [Pa2011]Journeys ——线段树优化连边
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=3073 建两棵线段树,一棵孩子向父亲连边,是走出去的:一棵父亲向孩子连边,是走进来的. 注意第 ...
- 【bzoj3073】[Pa2011]Journeys 线段树优化建图+堆优化Dijkstra
题目描述 Seter建造了一个很大的星球,他准备建造N个国家和无数双向道路.N个国家很快建造好了,用1..N编号,但是他发现道路实在太多了,他要一条条建简直是不可能的!于是他以如下方式建造道路:(a, ...
- BZOJ3073: [Pa2011]Journeys(线段树优化建图 Dijkstra)
题意 \(n\)个点的无向图,构造\(m\)次边,求\(p\)到任意点的最短路. 每次给出\(a, b, c, d\) 对于任意\((x_{a \leqslant x \leqslant b}, y_ ...
- BZOJ_3073_[Pa2011]Journeys_线段树优化建图+BFS
BZOJ_3073_[Pa2011]Journeys_线段树优化建图+BFS Description Seter建造了一个很大的星球,他准备建造N个国家和无数双向道路.N个国家很快建造好了,用1..N ...
- 【BZOJ3073】[Pa2011]Journeys 线段树+堆优化Dijkstra
[BZOJ3073][Pa2011]Journeys Description Seter建造了一个很大的星球,他准备建造N个国家和无数双向道路.N个国家很快建造好了,用1..N编号,但是他发现道路实在 ...
- 【题解】Journeys(线段树优化连边)
[#3073. Pa2011]Journeys (线段树优化连边) 这张图太直观了,直接讲透了线段树优化连边的原理和正确性. 考虑建立两颗线段树,一颗是外向树,一颗是内向树,相当于网络流建模一样,我们 ...
- DS线段树优化最短路&&01bfs浅谈
1简介 为什么需要?原因很简单,当需要有大量的边去连时,用线段树优化可以直接用点连向区间,或从区间连向点,或从区间连向区间,如果普通连边,复杂度是不可比拟的.下面简单讲解一下线段树(ST)优化建图. ...
- bzoj 3073 Journeys —— 线段树优化连边
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=3073 建两棵线段树,一棵从下往上连边,一棵从上往下连边,叶子节点之间也有连边: 区间向区间连 ...
- BZOJ 3073: [Pa2011]Journeys Dijkstra+线段树优化建图
复习一下线段树优化建图:1.两颗线段树的叶子节点的编号是公用的. 2.每次连边是要建两个虚拟节点 $p1,p2$ 并在 $p1,p2$ 之间连边. #include <bits/stdc++.h ...
随机推荐
- oracle01--单表查询
1. 基本(基础)查询 1.1. 基本查询语法 基本查询是指最基本的select语句. [语法] [知识点]如何使用工具进行查询 在plsql developer中打开查询窗口(执行sql语句): 执 ...
- java中的matches -> 完全匹配
matches是完全匹配.跟matcher不一样, matcher像perl正则, 能匹配到符合的都会返回true, 而这个matches要完全一模一样才行. import java.util.reg ...
- MAC泛洪攻击
先来解释一下啥是泛洪攻击 交换机里有一张专门记录MAC地址的表,为了完成数据的快速转发,该表具有自动学习机制:泛洪攻击即是攻击者利用这种学习机制不断发送不同的MAC地址给交换机,充满整个MAC表,此时 ...
- C++ 模板特化以及Typelist的相关理解
近日,在学习的过程中第一次接触到了Typelist的相关内容,比如Loki库有一本Modern C++ design的一本书,大概JD搜了一波没有译本,英文版600多R,瞬间从价值上看到了这本书的价值 ...
- CentOS7安装Hadoop2.7完整步骤
总体思路,准备主从服务器,配置主服务器可以无密码SSH登录从服务器,解压安装JDK,解压安装Hadoop,配置hdfs.mapreduce等主从关系. 1.环境,3台CentOS7,64位,Hadoo ...
- <转>MYSQL数据库数据拆分之分库分表总结
数据存储演进思路一:单库单表 单库单表是最常见的数据库设计,例如,有一张用户(user)表放在数据库db中,所有的用户都可以在db库中的user表中查到. 数据存储演进思路二:单库多表 随着用户数量的 ...
- 20165301 2017-2018-2 《Java程序设计》第六周学习总结
20165301 2017-2018-2 <Java程序设计>第六周学习总结 教材学习内容总结 第七章:常用实类 String类 构造String对象 常量对象 String对象 Stri ...
- [置顶]
人工智能(深度学习)加速芯片论文阅读笔记 (已添加ISSCC17,FPGA17...ISCA17...)
这是一个导读,可以快速找到我记录的关于人工智能(深度学习)加速芯片论文阅读笔记. ISSCC 2017 Session14 Deep Learning Processors: ISSCC 2017关于 ...
- 在LoadRunner中从数组类型的参数随机取值的方法
在LoadRunner中从数组类型的参数随机取值的方法 使用web_reg_save_param做关联后,有时候会有多个匹配值. 为了模仿用户行为随机取一个值为后续transcation所用,可以使用 ...
- controller中,Failed to Initialize. Reason: TimeOut虚拟用花初始化超时
1.调整 Run-timesetting->Internet Protocol->references->Advaanced->Options 将HTTP-request co ...