【BZOJ4456】 [Zjoi2016]旅行者 / 【UOJ #184】 【ZJOI2016】旅行者
Description
Input
Output
Sample Input
2
3
6 4
2
1 1 2 2
1 2 2 1
Sample Output
7
Solution
网格图求任意两点间的最短路。
可以用分治来解决。
之前校内训练的时候CJK学长出了一道IOI2013的题,就是用线段树来维护网格图的最短路。这题也很类似,离线询问以后,每次把长边拿出来分治,考虑经过中间这一排点的和没经过这一排点的。没经过的递归下去做,经过的就跑一遍堆优化dj或者spfa就好了。
Code
#include <cstdio>
#include <cstring> #define R register
#define maxn 20010
#define cmin(_a, _b) (_a > (_b) ? _a = (_b) : 0)
#define id(_a, _b) (((_a) - 1) * m + (_b) - 1)
#define id1(_x) ((_x) / m + 1)
#define id2(_x) ((_x) % m + 1)
int n, m;
struct Edge {
Edge *next;
int to, w;
} *last[maxn], e[maxn << ], *ecnt = e;
inline void link(R int a, R int b, R int w)
{
*++ecnt = (Edge) {last[a], b, w}; last[a] = ecnt;
*++ecnt = (Edge) {last[b], a, w}; last[b] = ecnt;
}
struct Ques {
int x1, y1, x2, y2, id;
} qu[], tmp[];
int ans[], dis[maxn], q[maxn * ], r[maxn], c[maxn];
bool inq[maxn];
#define inf 0x7fffffff
struct Data {
int pos, dis;
inline bool operator < (const Data &that) const {return dis > that.dis;}
} ;
#include <queue>
std::priority_queue<Data> hp;
void spfa(R int s, R int nl, R int nr, R int ml, R int mr)
{
//for (R int i = nl; i <= nr; ++i) for (R int j = ml; j <= mr; ++j) dis[id(i, j)] = inf;
/*
R int head = maxn * 20, tail = maxn * 20 + 1;
q[maxn * 20 + 1] = s; dis[s] = 0;
*/
hp.push((Data) {s, dis[s] = });
while (/*head < tail*/!hp.empty())
{
// R int now = q[++head]; inq[now] = 0;
R Data tp = hp.top(); hp.pop();
R int now = tp.pos;
for (R Edge *iter = last[now]; iter; iter = iter -> next)
if (dis[iter -> to] > dis[now] + iter -> w && nl <= id1(iter -> to) && id1(iter -> to) <= nr && ml <= id2(iter -> to) && id2(iter -> to) <= mr)
{
dis[iter -> to] = dis[now] + iter -> w;
// !inq[iter -> to] ? inq[dis[iter -> to] < dis[q[head + 1]] ? q[head--] = iter -> to : q[++tail] = iter -> to] = 1 : 0;
hp.push((Data) {iter -> to, dis[iter -> to]});
}
}
}
void work(R int nl, R int nr, R int ml, R int mr, R int ql, R int qr)
{
if (nl > nr || ml > mr) return ;
if (ql > qr) return ;
if (nr - nl + <= mr - ml + )
{
R int mid = ml + mr >> ;
for (R int i = nl; i <= nr; ++i) for (R int j = ml; j <= mr; ++j) dis[id(i, j)] = inf;
for (R int i = nl; i <= nr; ++i)
{
if (i != nl)
{
for (R int ii = nl; ii <= nr; ++ii) for (R int jj = ml; jj <= mr; ++jj)
dis[id(ii, jj)] += c[id(i - , mid)];
}
spfa(id(i, mid), nl, nr, ml, mr);
for (R int j = ql; j <= qr; ++j)
cmin(ans[qu[j].id], dis[id(qu[j].x1, qu[j].y1)] + dis[id(qu[j].x2, qu[j].y2)]);
}
R int qql = ql - , qqr = qr + ;
for (R int i = ql; i <= qr; ++i)
if (qu[i].y1 < mid && qu[i].y2 < mid)
tmp[++qql] = qu[i];
else if (qu[i].y1 > mid && qu[i].y2 > mid)
tmp[--qqr] = qu[i]; for (R int i = ql; i <= qql; ++i) qu[i] = tmp[i];
for (R int i = qqr; i <= qr; ++i) qu[i] = tmp[i];
work(nl, nr, ml, mid - , ql, qql);
work(nl, nr, mid + , mr, qqr, qr);
}
else
{
R int mid = nl + nr >> ;
for (R int i = nl; i <= nr; ++i) for (R int j = ml; j <= mr; ++j) dis[id(i, j)] = inf;
for (R int i = ml; i <= mr; ++i)
{
if (i != ml)
{
for (R int ii = nl; ii <= nr; ++ii) for (R int jj = ml; jj <= mr; ++jj)
dis[id(ii, jj)] += r[id(mid, i - )];
}
spfa(id(mid, i), nl, nr, ml, mr);
for (R int j = ql; j <= qr; ++j)
cmin(ans[qu[j].id], dis[id(qu[j].x1, qu[j].y1)] + dis[id(qu[j].x2, qu[j].y2)]);
}
R int qql = ql - , qqr = qr + ;
for (R int i = ql; i <= qr; ++i)
if (qu[i].x1 < mid && qu[i].x2 < mid)
tmp[++qql] = qu[i];
else if (qu[i].x1 > mid && qu[i].x2 > mid)
tmp[--qqr] = qu[i]; for (R int i = ql; i <= qql; ++i) qu[i] = tmp[i];
for (R int i = qqr; i <= qr; ++i) qu[i] = tmp[i];
work(nl, mid - , ml, mr, ql, qql);
work(mid + , nr, ml, mr, qqr, qr);
}
}
int main()
{
scanf("%d%d", &n, &m);
for (R int i = ; i <= n; ++i) for (R int j = ; j < m; ++j)
{R int w; scanf("%d", &w); link(id(i, j), id(i, j + ), w); r[id(i, j)] = w;}
for (R int i = ; i < n; ++i) for (R int j = ; j <= m; ++j)
{R int w; scanf("%d", &w); link(id(i, j), id(i + , j), w); c[id(i, j)] = w;}
R int Q; scanf("%d", &Q);
for (R int i = ; i <= Q; ++i) scanf("%d%d%d%d", &qu[i].x1, &qu[i].y1, &qu[i].x2, &qu[i].y2), qu[i].id = i;
memset(ans, , (Q + ) << );
work(, n, , m, , Q);
for (R int i = ; i <= Q; ++i) printf("%d\n", ans[i]);
return ;
}
【BZOJ4456】 [Zjoi2016]旅行者 / 【UOJ #184】 【ZJOI2016】旅行者的更多相关文章
- BZOJ4456/UOJ#184[Zjoi2016]旅行者 分治 最短路
原文链接http://www.cnblogs.com/zhouzhendong/p/8682133.html 题目传送门 - BZOJ4456 题目传送门 - UOJ#184 题意 $n\times ...
- 【BZOJ 4456】【UOJ #184】【ZJOI 2016】旅行者
http://www.lydsy.com/JudgeOnline/problem.php?id=4456 http://uoj.ac/problem/184 参考(抄)的晨爷的题解(代码) 对矩形进行 ...
- [CNBETA]动图告诉你 光速到底有多慢?
https://www.cnbeta.com/articles/tech/811381.htm 我们知道,30万公里每秒的光速是宇宙内目前已知的最高速度,至少现有人类理论体系下它是不可跨越的.30万公 ...
- bzoj4456: [Zjoi2016]旅行者
题目链接 bzoj4456: [Zjoi2016]旅行者 题解 网格图,对于图分治,每次从中间切垂直于长的那一边, 对于切边上的点做最短路,合并在图两边的答案. 有点卡常 代码 #include< ...
- 【BZOJ4456】[Zjoi2016]旅行者 分治+最短路
[BZOJ4456][Zjoi2016]旅行者 Description 小Y来到了一个新的城市旅行.她发现了这个城市的布局是网格状的,也就是有n条从东到西的道路和m条从南到北的道路,这些道路两两相交形 ...
- [BZOJ4456] [Zjoi2016]旅行者 分治+最短路
4456: [Zjoi2016]旅行者 Time Limit: 20 Sec Memory Limit: 512 MBSubmit: 777 Solved: 439[Submit][Status] ...
- BZOJ4456/UOJ184 [Zjoi2016]旅行者
本文版权归ljh2000和博客园共有,欢迎转载,但须保留此声明,并给出原文链接,谢谢合作. 本文作者:ljh2000 作者博客:http://www.cnblogs.com/ljh2000-jump/ ...
- BZOJ4456 ZJOI2016旅行者(分治+最短路)
感觉比较套路,每次在长边中轴线处切一刀,求出切割线上的点对矩形内所有点的单源最短路径,以此更新每个询问,递归处理更小的矩形.因为若起点终点跨过中轴线是肯定要经过的,而不跨过中轴线的则可以选择是否经过中 ...
- [BZOJ4456][ZJOI2016]旅行者:分治+最短路
分析 类似于点分治的思想,只统计经过分割线的最短路,然后把地图一分为二. 代码 #include <bits/stdc++.h> #define rin(i,a,b) for(regist ...
随机推荐
- Hive 教程(二)-认知hive
在大数据领域,hive 的位置非常重要,排名前三的大数据工具为 spark.hive.kafka 什么是hive 在大数据领域有 3 种需求场景:传输.存储.计算: hive 是一个处理海量的结构化数 ...
- myBatis+Spring+SpringMVC框架面试题整理
myBatis+Spring+SpringMVC框架面试题整理(一) 2018年09月06日 13:36:01 新新许愿树 阅读数 14034更多 分类专栏: SSM 版权声明:本文为博主原创文章 ...
- Dockerfile安装jdk1.8 、部署java项目
基础指令 FROM 基于哪个镜像MAINTAINER 用来写备注信息,例如作者.日期等.COPY 复制文件进入镜像(只能用相对路径,不能用绝对路径)ADD 复制文件进入镜像(可以用绝对路径,假如是压缩 ...
- vue cli更新
关于旧版本 Vue CLI 的包名称由 vue-cli 改成了 @vue/cli. 如果你已经全局安装了旧版本的 vue-cli (1.x 或 2.x),你需要先通过 npm uninstall vu ...
- with as 语句
with就是一个sql片段,供后面的sql语句引用. 详情参见:https://www.cnblogs.com/Niko12230/p/5945133.html
- Centos7:zookeeper安装,配置与使用
配置jdk环境 解压缩zookeeper的压缩包 配置 创建data目录 复制zoo_sample.cfg为zoo.cfg 修改confg/zoo.cfg中dataDir=**/data 常用命令 . ...
- bilibili小程序项目总结
1.关于mock的使用 第一步:先到Mock官网(http://mockjs.com/)上面熟悉一下基本用法 第一步:具体使用实例: 下载wxMock.js和mock.js文件 下载地址:https: ...
- new Date,Date.parse()传值
获取时间: 获取1997年10月1号日期 new Date: 当使用 - 拼接年月日时将会使用UTC时区解析参数,会比北京时间快八小时. 当时用 / 拼接年月日时会使用北京的时区去解析参数,取到的是北 ...
- cefsharp webBrowser Javascript 打开winForm界面
在Cef webBrowser中,如果要调用 Javascript打开 一个 winForm界面,则需要使用 ShowDialog(),而不能使用 Show(),否则界面上的鼠标会转个不停
- TableView 键盘弹起冲突
1.TableView 上cell 带有 TextField,如果 是Plain 形式的TableView ,并且设置SectionHeader的 取消粘滞效果 会导致键盘弹起,页面不能正常 上移 问 ...