#分治,Dijkstra#洛谷 3350 [ZJOI2016]旅行者
题目
给定一张\(n*m\)的网格图,\(q\)次询问两点之间距离
\(n*m\leq 2*10^4,q\leq 10^5\)
分析
首先floyd会TLE,考虑两点间距离可以由两段拼凑起来,
那么枚举中间点然后跑单源最短路,但是这样与floyd时间复杂度无异,
一些中间点实际上完全不需要,考虑分治,每次选取中线上的点在子图内跑单源最短路
据说时间复杂度是\(O(nm\sqrt{nm}\log{nm})\)
代码
#include <cstdio>
#include <cctype>
#include <algorithm>
#define rr register
using namespace std;
const int N=20011,inf=0x3f3f3f3f; struct node{int y,w,next;}e[N<<2];
struct rec{int lx,ly,rx,ry,rk;}q[N*5],q1[N*5],q2[N*5];
struct Two{
int d,x;
inline bool operator <(const Two &t)const{
return d<t.d;
}
};
int as[N],Cnt,et=1,Q,dis[N],ans[N*5],n,m,Lx,Ly,Rx,Ry; Two heap[N];
inline signed iut(){
rr int ans=0; rr char c=getchar();
while (!isdigit(c)) c=getchar();
while (isdigit(c)) ans=(ans<<3)+(ans<<1)+(c^48),c=getchar();
return ans;
}
inline void print(int ans){
if (ans>9) print(ans/10);
putchar(ans%10+48);
}
inline void add(int x,int y,int w){
e[++et]=(node){y,w,as[x]},as[x]=et;
e[++et]=(node){x,w,as[y]},as[y]=et;
}
inline signed min(int a,int b){return a<b?a:b;}
inline void Push(Two w){
heap[++Cnt]=w;
rr int x=Cnt;
while (x>1){
if (heap[x]<heap[x>>1])
swap(heap[x],heap[x>>1]),x>>=1;
else return;
}
}
inline void Pop(){
heap[1]=heap[Cnt--];
rr int x=1;
while ((x<<1)<=Cnt){
rr int y=x<<1;
if (y<Cnt&&heap[y+1]<heap[y]) ++y;
if (heap[y]<heap[x]) swap(heap[x],heap[y]),x=y;
else return;
}
}
inline signed rk(int x,int y){return (x-1)*m+y;}
inline bool Into(int Rk){
rr int x=(Rk-1)/m+1,y=Rk-(x-1)*m;
return Lx<=x&&x<=Rx&&Ly<=y&&y<=Ry;
}
inline void Dijkstra(int S){
if (dis[S]){
for (rr int i=Lx;i<=Rx;++i)
for (rr int j=Ly;j<=Ry;++j)
if (rk(i,j)!=S) dis[rk(i,j)]+=dis[S];
}else for (rr int i=Lx;i<=Rx;++i)
for (rr int j=Ly;j<=Ry;++j)
dis[rk(i,j)]=inf;
heap[++Cnt]=(Two){0,S},dis[S]=0;
while (Cnt){
rr Two t=heap[1];
Pop(); if (t.d!=dis[t.x]) continue;
for (rr int i=as[t.x];i;i=e[i].next)
if (Into(e[i].y)&&dis[e[i].y]>dis[t.x]+e[i].w){
dis[e[i].y]=dis[t.x]+e[i].w;
Push((Two){dis[e[i].y],e[i].y});
}
}
}
inline void dfs(int lx,int rx,int ly,int ry,int l,int r){
if (l>r) return;
if (lx==rx&&ly==ry){
for (rr int i=l;i<=r;++i) ans[q[i].rk]=0;
return;
}
Lx=lx,Rx=rx,Ly=ly,Ry=ry;
if (rx-lx>ry-ly){
rr int mid=(lx+rx)>>1,tot1=0,tot2=0;
for (rr int i=ly;i<=ry;++i){
Dijkstra(rk(mid,i));
for (rr int j=l;j<=r;++j)
ans[q[j].rk]=min(ans[q[j].rk],dis[rk(q[j].lx,q[j].ly)]+dis[rk(q[j].rx,q[j].ry)]);
}
for (rr int i=l;i<=r;++i){
if (lx<=q[i].lx&&q[i].lx<=mid&&lx<=q[i].rx&&q[i].rx<=mid) q1[++tot1]=q[i];
if (mid+1<=q[i].lx&&q[i].lx<=rx&&mid+1<=q[i].rx&&q[i].rx<=rx) q2[++tot2]=q[i];
}
for (rr int i=1;i<=tot1;++i) q[i+l-1]=q1[i];
for (rr int i=1;i<=tot2;++i) q[r-i+1]=q2[i];
dfs(lx,mid,ly,ry,l,l+tot1-1);
dfs(mid+1,rx,ly,ry,r-tot2+1,r);
}else{
rr int mid=(ly+ry)>>1,tot1=0,tot2=0;
for (rr int i=lx;i<=rx;++i){
Dijkstra(rk(i,mid));
for (rr int j=l;j<=r;++j)
ans[q[j].rk]=min(ans[q[j].rk],dis[rk(q[j].lx,q[j].ly)]+dis[rk(q[j].rx,q[j].ry)]);
}
for (rr int i=l;i<=r;++i){
if (ly<=q[i].ly&&q[i].ly<=mid&&ly<=q[i].ry&&q[i].ry<=mid) q1[++tot1]=q[i];
if (mid+1<=q[i].ly&&q[i].ly<=ry&&mid+1<=q[i].ry&&q[i].ry<=ry) q2[++tot2]=q[i];
}
for (rr int i=1;i<=tot1;++i) q[i+l-1]=q1[i];
for (rr int i=1;i<=tot2;++i) q[r-i+1]=q2[i];
dfs(lx,rx,ly,mid,l,l+tot1-1);
dfs(lx,rx,mid+1,ry,r-tot2+1,r);
}
}
signed main(){
n=iut(),m=iut();
for (rr int i=1;i<=n;++i)
for (rr int j=1;j<m;++j)
add(rk(i,j),rk(i,j+1),iut());
for (rr int i=1;i<n;++i)
for (rr int j=1;j<=m;++j)
add(rk(i,j),rk(i+1,j),iut());
Q=iut();
for (rr int i=1;i<=Q;++i)
ans[i]=inf,q[i]=(rec){iut(),iut(),iut(),iut(),i};
dfs(1,n,1,m,1,Q);
for (rr int i=1;i<=Q;++i) print(ans[i]),putchar(10);
return 0;
}
#分治,Dijkstra#洛谷 3350 [ZJOI2016]旅行者的更多相关文章
- 洛谷P3348 [ZJOI2016]大森林(LCT,虚点,树上差分)
洛谷题目传送门 思路分析 最简单粗暴的想法,肯定是大力LCT,每个树都来一遍link之类的操作啦(T飞就不说了) 考虑如何优化算法.如果没有1操作,肯定每个树都长一样.有了1操作,就来仔细分析一下对不 ...
- 洛谷 P3349 [ZJOI2016]小星星 解题报告
P3349 [ZJOI2016]小星星 题目描述 小\(Y\)是一个心灵手巧的女孩子,她喜欢手工制作一些小饰品.她有\(n\)颗小星星,用\(m\)条彩色的细线串了起来,每条细线连着两颗小星星. 有一 ...
- Luogu 3350 [ZJOI2016]旅行者
BZOJ 4456 听若干个大佬讲过$n$遍终于写掉了. 我把时限基本上跑满了2333…… 分治 + 最短路. 首先我们去分治这个矩形格子,找到一条长边把它对半切,对切开的边上的每一个点跑一遍最短路然 ...
- ●洛谷P3348 [ZJOI2016]大森林
题链: https://www.luogu.org/problemnew/show/P3348 题解: LCT,神题 首先有这么一个结论: 每次的1操作(改变生长点操作),一定只会会对连续的一段区间产 ...
- 洛谷P3348 [ZJOI2016]大森林 [LCT]
传送门 刷了那么久水题之后终于有一题可以来写写博客了. 但是这题太神仙了我还没完全弄懂-- upd:写完博客之后似乎懂了. 思路 首先很容易想到\(O(n^2\log n)\)乘上\(O(\frac{ ...
- [洛谷P2605] ZJOI2016 基站选址
问题描述 有N个村庄坐落在一条直线上,第i(i>1)个村庄距离第1个村庄的距离为Di.需要在这些村庄中建立不超过K个通讯基站,在第i个村庄建立基站的费用为Ci.如果在距离第i个村庄不超过Si的范 ...
- [BZOJ4456] [Zjoi2016]旅行者 分治+最短路
4456: [Zjoi2016]旅行者 Time Limit: 20 Sec Memory Limit: 512 MBSubmit: 777 Solved: 439[Submit][Status] ...
- Bzoj4016/洛谷P2993 [FJOI2014] 最短路径树问题(最短路径问题+长链剖分/点分治)
题面 Bzoj 洛谷 题解 首先把最短路径树建出来(用\(Dijkstra\),没试过\(SPFA\)\(\leftarrow\)它死了),然后问题就变成了一个关于深度的问题,可以用长链剖分做,所以我 ...
- 【BZOJ4456】[Zjoi2016]旅行者 分治+最短路
[BZOJ4456][Zjoi2016]旅行者 Description 小Y来到了一个新的城市旅行.她发现了这个城市的布局是网格状的,也就是有n条从东到西的道路和m条从南到北的道路,这些道路两两相交形 ...
- 洛谷.3733.[HAOI2017]八纵八横(线性基 线段树分治 bitset)
LOJ 洛谷 最基本的思路同BZOJ2115 Xor,将图中所有环的异或和插入线性基,求一下线性基中数的异或最大值. 用bitset优化一下,暴力的复杂度是\(O(\frac{qmL^2}{w})\) ...
随机推荐
- 【Android 逆向】【攻防世界】APK逆向
1. apk安装到手机,提示输入flag 2. jadx打开apk 定位到checkSN方法 public boolean checkSN(String userName, String sn) { ...
- macOS使用CodeRunner快速配置fortran环境
个人网站:xzajyjs.cn 由于一些项目的缘故,需要有fortran的需求,但由于是M1 mac的缘故,不能像windows那样直接使用vs+ivf这种经典配置.搜了一下网上主流的跨平台方案,主要 ...
- Jina AI x 矩池云Matpool |神经搜索引擎,一键构建
图片.视频.语音等非结构化数据在快速增长,随着深度学习技术的不断升级,非结构化数据的搜索也逐渐形成可能.在这样的背景下,专注于神经搜索技术的商业开源软件公司--Jina AI,提出了神经搜索 (Neu ...
- 【Azure 服务总线】Azure.Messaging.ServiceBus 多次发送消息报超时错误,是否可以配置重新发送?是否有内置重试机制?
问题描述 使用 Azure Service Bus,提供应用程序之间松耦合的消息交换,但是有时候发送消息多次出现超时错误. A connection attempt failed because th ...
- 【Azure 事件中心】Flink消费Event Hub中事件, 使用Azure默认示例代码,始终获取新产生的事件,如何消费旧事件呢?
问题描述 根据Azure Event Hub示例文档,[将 Apache Flink 与适用于 Apache Kafka 的 Azure 事件中心配合使用],配置好 consumer.config 文 ...
- 【Azure API 管理】APIM服务资源删除后,为什么不能马上创建相同名称的APIM服务呢?
问题描述 使用Azure APIM服务,在删除旧资源准备新建相同名称的新APIM服务时,尝试多次都是出现"指定的服务名称已正在使用"错误.但实际上同名称的服务已经被删除.为什么多次 ...
- 图查询语言 nGQL 简明教程 vol.01 快速入门
本文旨在让新手快速了解 nGQL,掌握方向,之后可以脚踩在地上借助文档写出任何心中的 NebulaGraph 图查询. 视频 本教程的视频版在B站这里. 准备工作 在正式开始 nGQL 实操之前,记得 ...
- ChatGPT用10秒画完一张UML流程图,而我用了。。。
不用AI的程序员,失业潮真的快来临了. 一张订单履约的流程图,我花了10分钟才完成,而ChatGPT绘图过程只用了10秒钟,基本可以达到同样的水平,通过ChatGPT可以显著提高画流程图的效率. 订单 ...
- redis---面经
redis 偏应用的总结:redis 应用 Redis是什么? Redis是什么 对象 字符串 自增,键值对. SDS数据结构记录长度,已经使用,和总共长度,并且提前多余出容量,防止一直扩容缩容. 字 ...
- MySQL8.0与5.7版本的下载、安装与配置
•软件下载 下载地址 [官网],点开该网址,点击 DOWNLOAD 来到如下页面: MySQL的版本介绍 MySQL Community Server 社区版本:开源免费,自由下载,但不提供官方技 ...