分析

类似于点分治的思想,只统计经过分割线的最短路,然后把地图一分为二。

代码

#include <bits/stdc++.h>
#define rin(i,a,b) for(register int i=(a);i<=(b);++i)
#define irin(i,a,b) for(register int i=(a);i>=(b);--i)
#define trav(i,a) for(register int i=head[a];i;i=e[i].nxt)
typedef long long LL;
using std::cin;
using std::cout;
using std::endl; inline int read(){
int x=0,f=1;char ch=getchar();
while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();}
while(isdigit(ch)){x=x*10+ch-'0';ch=getchar();}
return x*f;
} const int MAXN=200005; int n,m,q,*r[MAXN],*c[MAXN],ans[MAXN];
int dis[MAXN];
int dx[4]={-1,1,0,0},dy[4]={0,0,-1,1};
bool vis[MAXN]; struct Qu{
int sx,sy,tx,ty,id;
}a[MAXN],b[MAXN]; struct Pair{
int pos,dis;
inline friend bool operator > (Pair x,Pair y){
return x.dis>y.dis;
}
}; std::priority_queue<Pair,std::vector<Pair>,std::greater<Pair> > pq; inline int id(int x,int y){
return (x-1)*m+y;
} void dijkstra(int sx,int sy,int sn,int tn,int sm,int tm){
rin(i,sn,tn) rin(j,sm,tm) dis[id(i,j)]=1e9,vis[id(i,j)]=false;
while(!pq.empty()) pq.pop();
dis[id(sx,sy)]=0;
pq.push((Pair){id(sx,sy),0});
while(!pq.empty()){
int idx=pq.top().pos;pq.pop();
if(vis[idx]) continue;
vis[idx]=true;
int x=(idx-1)/m+1,y=idx-(x-1)*m;
rin(i,0,3){
int xx=x+dx[i],yy=y+dy[i],w=0;
if(xx<sn||xx>tn||yy<sm||yy>tm||vis[id(xx,yy)]) continue;
if(i==0) w=c[xx][yy];
else if(i==1) w=c[x][y];
else if(i==2) w=r[xx][yy];
else w=r[x][y];
if(dis[id(xx,yy)]>dis[idx]+w){
dis[id(xx,yy)]=dis[idx]+w;
pq.push((Pair){id(xx,yy),dis[id(xx,yy)]});
}
}
}
} void solve(int sn,int tn,int sm,int tm,int sq,int tq){
if(sn>tn||sm>tm||sq>tq) return;
if(tn-sn<tm-sm){
int mid=((sm+tm)>>1);
rin(i,sn,tn){
dijkstra(i,mid,sn,tn,sm,tm);
rin(j,sq,tq){
ans[a[j].id]=std::min(ans[a[j].id],
dis[id(a[j].sx,a[j].sy)]+dis[id(a[j].tx,a[j].ty)]);
}
}
int top=0;
rin(i,sq,tq) if(a[i].sy<mid&&a[i].ty<mid) b[++top]=a[i];
int temp=top;
rin(i,sq,tq) if(a[i].sy>mid&&a[i].ty>mid) b[++top]=a[i];
memcpy(a+sq,b+1,top*sizeof(Qu));
solve(sn,tn,sm,mid-1,sq,sq+temp-1);
solve(sn,tn,mid+1,tm,sq+temp,sq+top-1);
}
else{
int mid=((sn+tn)>>1);
rin(i,sm,tm){
dijkstra(mid,i,sn,tn,sm,tm);
rin(j,sq,tq){
ans[a[j].id]=std::min(ans[a[j].id],
dis[id(a[j].sx,a[j].sy)]+dis[id(a[j].tx,a[j].ty)]);
}
}
int top=0;
rin(i,sq,tq) if(a[i].sx<mid&&a[i].tx<mid) b[++top]=a[i];
int temp=top;
rin(i,sq,tq) if(a[i].sx>mid&&a[i].tx>mid) b[++top]=a[i];
memcpy(a+sq,b+1,top*sizeof(Qu));
solve(sn,mid-1,sm,tm,sq,sq+temp-1);
solve(mid+1,tn,sm,tm,sq+temp,sq+top-1);
}
} int main(){
n=read(),m=read();
rin(i,1,n) r[i]=new int [m+5],c[i]=new int [m+5];
rin(i,1,n) rin(j,1,m-1) r[i][j]=read();
rin(i,1,n-1) rin(j,1,m) c[i][j]=read();
q=read();
rin(i,1,q){
a[i].sx=read();
a[i].sy=read();
a[i].tx=read();
a[i].ty=read();
a[i].id=i;
ans[i]=1e9;
}
solve(1,n,1,m,1,q);
rin(i,1,q) printf("%d\n",ans[i]);
return 0;
}

[BZOJ4456][ZJOI2016]旅行者:分治+最短路的更多相关文章

  1. [BZOJ4456] [Zjoi2016]旅行者 分治+最短路

    4456: [Zjoi2016]旅行者 Time Limit: 20 Sec  Memory Limit: 512 MBSubmit: 777  Solved: 439[Submit][Status] ...

  2. 【BZOJ4456】[Zjoi2016]旅行者 分治+最短路

    [BZOJ4456][Zjoi2016]旅行者 Description 小Y来到了一个新的城市旅行.她发现了这个城市的布局是网格状的,也就是有n条从东到西的道路和m条从南到北的道路,这些道路两两相交形 ...

  3. 【BZOJ-4456】旅行者 分治 + 最短路

    4456: [Zjoi2016]旅行者 Time Limit: 20 Sec  Memory Limit: 512 MBSubmit: 254  Solved: 162[Submit][Status] ...

  4. BZOJ4456/UOJ#184[Zjoi2016]旅行者 分治 最短路

    原文链接http://www.cnblogs.com/zhouzhendong/p/8682133.html 题目传送门 - BZOJ4456 题目传送门 - UOJ#184 题意 $n\times ...

  5. 【BZOJ4456】旅行者(最短路,分治)

    [BZOJ4456]旅行者(最短路,分治) 题面 BZOJ Description 小Y来到了一个新的城市旅行.她发现了这个城市的布局是网格状的,也就是有n条从东到西的道路和m条从南到北 的道路,这些 ...

  6. bzoj4456: [Zjoi2016]旅行者

    题目链接 bzoj4456: [Zjoi2016]旅行者 题解 网格图,对于图分治,每次从中间切垂直于长的那一边, 对于切边上的点做最短路,合并在图两边的答案. 有点卡常 代码 #include< ...

  7. BZOJ4456 ZJOI2016旅行者(分治+最短路)

    感觉比较套路,每次在长边中轴线处切一刀,求出切割线上的点对矩形内所有点的单源最短路径,以此更新每个询问,递归处理更小的矩形.因为若起点终点跨过中轴线是肯定要经过的,而不跨过中轴线的则可以选择是否经过中 ...

  8. BZOJ.4456.[ZJOI2016]旅行者(分治 Dijkstra)

    题目链接 \(Description\) 给定\(n\times m\)的带边权网格图.\(Q\)次询问从点\((x_i,y_i)\)到点\((x_j,y_j)\)的最短路. \(n\times m\ ...

  9. 4456: [Zjoi2016]旅行者

    4456: [Zjoi2016]旅行者 https://www.lydsy.com/JudgeOnline/problem.php?id=4456 分析: 每次对当前矩阵按长边化一条分治线,然后在对分 ...

随机推荐

  1. numpy使用数组进行数据处理

    numpy使用数组进行数据处理 meshgrid函数 理解: 二维坐标系中,X轴可以取三个值1,2,3, Y轴可以取三个值7,8, 请问可以获得多少个点的坐标? 显而易见是6个: (1,7)(2,7) ...

  2. springBoot2.0 Yaml值获取

    1. pom.xml添加如下依赖 <dependency> <groupId>org.springframework.boot</groupId> <arti ...

  3. Flask-wtf导入Regexp规则库验证手机号码合法性(测试通过)

    手机号码在项目有着很重要的地位,保证用户输入的号码准确无误就显得很关键. 废话不多说,现在页面中引入Regexp规则库: from wtforms.validators import Regexp 验 ...

  4. MUI沉浸式代码

    var ben_immer = (function() { var immersed = 0; var ms = (/Html5Plus\/.+\s\(.*(Immersed\/(\d+\.?\d*) ...

  5. [Vue] vue的一些面试题3

    1. vue 组件里的定时器要怎么销毁? 当生命周期销毁后,并没有将组件中的计时器销毁,虽然页面上看不出来,但是如果在控制台打印的话,会发现计时器还在运行,所以要销毁计时器,避免代码一直执行 cons ...

  6. .net 分布式锁

    原文 : 浅解.Net分布式锁的实现   序言 我晚上有在公司多呆会儿的习惯,所以很多晚上我都是最后一个离开公司的.当然也有一些同事,跟我一样喜欢在公司多搞会儿.这篇文章就要从,去年年末一个多搞会的晚 ...

  7. NTFS,FAT32和exFAT文件系统的区别

    NTFS,FAT32和exFAT文件系统的区别 本文所有资料来源于网络,仅做个人学习使用,如有侵权,请联系删除 1.什么是文件系统 文件系统是系统对文件的存放排列方式,不同格式的文件系统关系到数据是如 ...

  8. 单元测试 - tox 使用

    1. 问题一 $ tox -e pep8 -- testdemo.server pep8 installed: alembic==,amqp==,appdirs==,Babel==,beautiful ...

  9. vue-cli解决兼容ie的es6+api问题

    官网:https://cli.vuejs.org/zh/guide/browser-compatibility.html#usebuiltins-usage https://github.com/vu ...

  10. ftp建立虚拟用户实现文件上传和下载

    环境 centos7 1.开启vsftpd服务 2.检查vsftpd服务是否开启 3.添加虚拟用户口令文件 vi etc/vsftpd/vuser.txt 4.生成虚拟用户口令认证文件 如果没有db_ ...