Luogu 3350 [ZJOI2016]旅行者
BZOJ 4456
听若干个大佬讲过$n$遍终于写掉了。
我把时限基本上跑满了2333……
分治 + 最短路。
首先我们去分治这个矩形格子,找到一条长边把它对半切,对切开的边上的每一个点跑一遍最短路然后更新所有答案,接下来把询问分成两类,一类是两个端点都在切开的中间线一侧的,另一类是在两侧的。对于在中轴线一侧的点,我们把它加到一侧去继续分治,而在中轴线两侧的点就不用继续分治了,因为接下来的中轴线一定不会对它造成影响。
分治边界是没有对应询问的情况和只剩下一个点但是仍然有询问的情况,这时候可以直接用$0$更新当前的答案。
不会算时间复杂度,这篇博客证明是$O(S\sqrt{S}logS)$的,其中$S$代表面积。
另外,听说$spfa$比$dijskra$跑得快……
Code:
#include <cstdio>
#include <cstring>
#include <queue>
#include <iostream>
using namespace std;
typedef pair <int, int> pin; const int N = 2e4 + ;
const int M = 1e5 + ;
const int inf = 0x3f3f3f3f; int n, m, qn, tot = , head[N], dis[N], ans[M], verx[N], very[N];
bool vis[N];
priority_queue <pin> Q; struct Edge {
int to, nxt, val;
} e[N << ]; inline void add(int from, int to, int val) {
e[++tot].to = to;
e[tot].val = val;
e[tot].nxt = head[from];
head[from] = tot;
} inline void addEdge(int x, int y, int val) {
add(x, y, val), add(y, x, val);
} struct Querys {
int xa, xb, ya, yb, id;
} q[M], tmp[M]; inline void read(int &X) {
X = ; char ch = ; int op = ;
for(; ch > '' || ch < ''; ch = getchar())
if(ch == '-') op = -;
for(; ch >= '' && ch <= ''; ch = getchar())
X = (X << ) + (X << ) + ch - ;
X *= op;
} inline void chkMin(int &x, int y) {
if(y < x) x = y;
} inline int id(int x, int y) {
return (x - ) * m + y;
} void dij(int xl, int xr, int yl, int yr, int stx, int sty) {
for(int i = xl; i <= xr; i++)
for(int j = yl; j <= yr; j++)
dis[id(i, j)] = inf, vis[id(i, j)] = ; dis[id(stx, sty)] = ;
Q.push(pin(, id(stx, sty)));
for(; !Q.empty(); ) {
int x = Q.top().second; Q.pop();
if(vis[x]) continue;
vis[x] = ;
for(int i = head[x]; i; i = e[i].nxt) {
int y = e[i].to;
if(verx[y] >= xl && verx[y] <= xr && very[y] >= yl && very[y] <= yr) {
if(dis[y] > dis[x] + e[i].val) {
dis[y] = dis[x] + e[i].val;
Q.push(pin(-dis[y], y));
}
}
}
}
} void solve(int xl, int xr, int yl, int yr, int ql, int qr) {
if(ql > qr) return; if(xl == xr && yl == yr) {
for(int i = ql; i <= qr; i++)
chkMin(ans[q[i].id], );
return;
} if(xr - xl > yr - yl) {
int mid = ((xl + xr) >> );
for(int i = yl; i <= yr; i++) {
dij(xl, xr, yl, yr, mid, i);
for(int j = ql; j <= qr; j++) {
int x = id(q[j].xa, q[j].ya), y = id(q[j].xb, q[j].yb);
chkMin(ans[q[j].id], dis[x] + dis[y]);
}
} int l = ql - , r = qr + ;
for(int i = ql; i <= qr; i++) {
if(q[i].xa <= mid && q[i].xb <= mid) tmp[++l] = q[i];
else if(q[i].xa > mid && q[i].xb > mid) tmp[--r] = q[i];
}
for(int i = ql; i <= l; i++) q[i] = tmp[i];
for(int i = r; i <= qr; i++) q[i] = tmp[i]; solve(xl, mid, yl, yr, ql, l);
solve(mid + , xr, yl, yr, r, qr);
} else {
int mid = ((yl + yr) >> );
for(int i = xl; i <= xr; i++) {
dij(xl, xr, yl, yr, i, mid);
for(int j = ql; j <= qr; j++) {
int x = id(q[j].xa, q[j].ya), y = id(q[j].xb, q[j].yb);
chkMin(ans[q[j].id], dis[x] + dis[y]);
}
} int l = ql - , r = qr + ;
for(int i = ql; i <= qr; i++) {
if(q[i].ya <= mid && q[i].yb <= mid) tmp[++l] = q[i];
else if(q[i].ya > mid && q[i].yb > mid) tmp[--r] = q[i];
}
for(int i = ql; i <= l; i++) q[i] = tmp[i];
for(int i = r; i <= qr; i++) q[i] = tmp[i]; solve(xl, xr, yl, mid, ql, l);
solve(xl, xr, mid + , yr, r, qr);
}
} int main() {
// freopen("tourist3.in", "r", stdin);
// freopen("my.out", "w", stdout);
// freopen("Sample.txt", "r", stdin); read(n), read(m); for(int i = ; i <= n; i++)
for(int j = ; j <= m; j++)
verx[id(i, j)] = i, very[id(i, j)] = j; /* for(int i = 1; i <= n; i++)
for(int j = 1; j <= m; j++)
printf("%d %d %d\n", id(i, j), verx[id(i, j)], very[id(i, j)]); */ for(int i = ; i <= n; i++)
for(int j = ; j < m; j++) {
int v; read(v);
addEdge(id(i, j), id(i, j + ), v);
}
for(int i = ; i < n; i++)
for(int j = ; j <= m; j++) {
int v; read(v);
addEdge(id(i, j), id(i + , j), v);
} read(qn);
for(int i = ; i <= qn; i++) {
read(q[i].xa), read(q[i].ya), read(q[i].xb), read(q[i].yb);
q[i].id = i;
} memset(ans, 0x3f, sizeof(ans));
solve(, n, , m, , qn); for(int i = ; i <= qn; i++)
printf("%d\n", ans[i]); return ;
}
Luogu 3350 [ZJOI2016]旅行者的更多相关文章
- P3350 [ZJOI2016]旅行者
题目描述 小Y来到了一个新的城市旅行.她发现了这个城市的布局是网格状的,也就是有n条从东到西的道路和m条从南到北的道路,这些道路两两相交形成n*m个路口 (i,j)(1<=i<=n,1&l ...
- bzoj4456: [Zjoi2016]旅行者
题目链接 bzoj4456: [Zjoi2016]旅行者 题解 网格图,对于图分治,每次从中间切垂直于长的那一边, 对于切边上的点做最短路,合并在图两边的答案. 有点卡常 代码 #include< ...
- 4456: [Zjoi2016]旅行者
4456: [Zjoi2016]旅行者 https://www.lydsy.com/JudgeOnline/problem.php?id=4456 分析: 每次对当前矩阵按长边化一条分治线,然后在对分 ...
- [BZOJ4456] [Zjoi2016]旅行者 分治+最短路
4456: [Zjoi2016]旅行者 Time Limit: 20 Sec Memory Limit: 512 MBSubmit: 777 Solved: 439[Submit][Status] ...
- 【BZOJ4456】[Zjoi2016]旅行者 分治+最短路
[BZOJ4456][Zjoi2016]旅行者 Description 小Y来到了一个新的城市旅行.她发现了这个城市的布局是网格状的,也就是有n条从东到西的道路和m条从南到北的道路,这些道路两两相交形 ...
- luogu3350 [ZJOI2016]旅行者
链接 P3350 [ZJOI2016]旅行者 题目大意:给出网格图,求两点之间最短路,多组询问. \(n*m\leq10^5\ \ q\leq 10^5\) 考虑\(CDQ\)分治. 首先把询问离线, ...
- Luogu3350 ZJOI2016 旅行者 最短路、分治
传送门 题意:给出一个$N \times M$的网格图,边有边权,$Q$组询问,每组询问$(x_1,y_1)$到$(x_2,y_2)$的最短路.$N \times M \leq 2 \times 10 ...
- ●BOZJ 4456 [Zjoi2016]旅行者
题链: http://www.lydsy.com/JudgeOnline/problem.php?id=4456 题解: 分治好题.大致做法如下:对于一开始的矩形区域,过较长边的中点把矩形区域分为两个 ...
- [ZJOI2016]旅行者
题目描述 小Y来到了一个新的城市旅行.她发现了这个城市的布局是网格状的,也就是有n条从东到西的道路和m条从南到北的道路,这些道路两两相交形成n*m个路口 (i,j)(1<=i<=n,1&l ...
随机推荐
- Storm开发过程中的问题与建议
转自:http://blog.csdn.net/ouyang111222/article/details/50061305 (一) topology层级建议设不要设置过多 storm讲究是流式计算,s ...
- 【WCF安全】使用X509证书自定义验证
接触WCF时间比较短,在项目中要使用X509证书,纠结好几天终于有了结论,因此为了方便日后查阅和园友交流特意单独将部分代码提出,并做以记录. 1.准备工作 制作X509证书,此处用到三个证书名称 导入 ...
- Eclipse执行import命令导入maven项目时报错:Add a version or custom suffix using "Name template" in "Advanced" settings
新建了两个maven项目在E盘workspace目录,后面移到workspace/app_engine目录下提交svn,再通过Eclipse的File->import导入时报错了: Projec ...
- 用 Python 实现文件查找
用 Python 实现文件查找(BIF实现及队列实现) (1)利用内置函数实现文件查找 1.功能:返回用户输入的文件的绝对路径 2.设计思路: (1)用户输入在哪个盘进行查找 (2)遍历此盘文件,若为 ...
- 蓝桥杯 算法训练 ALGO-114 黑白无常
算法训练 黑白无常 时间限制:1.0s 内存限制:256.0MB 问题描述 某寝室的同学们在学术完之后准备玩一个游戏:游戏是这样的,每个人头上都被贴了一张白色或者黑色的纸,现在每个人都会说一句 ...
- FTP for win7
In Windows 7, you can share files on home network easily using Home Group but creating an FTP server ...
- jQuery选择器this通过onclick传入方法以及Jquery中的this与$(this)初探,this传处变量等
起初以为this和$(this)就是一模子刻出来.但是我在阅读时,和coding时发现,总不是一回事. <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML ...
- 拦截导弹简单版(读入一串整数时getline(cin,s) stringstream is(s);)
拦截导弹简单版 时间限制: 1 Sec 内存限制: 128 MB提交: 40 解决: 16[提交][状态][讨论版][命题人:外部导入] 题目描述 某国为了防御敌国的导弹袭击,发展出一种导弹拦截系 ...
- AngularJS:控制器
ylbtech-AngularJS:控制器 1.返回顶部 1. AngularJS 控制器 AngularJS 控制器 控制 AngularJS 应用程序的数据. AngularJS 控制器是常规的 ...
- Centos7部署CephFS
标签(空格分隔): ceph环境,ceph,cephfs cephfs部署之前准备工作: 1. 一个 clean+active 的cluster cluster部署参考:centos7下搭建ceph ...