题解

每次按较长边把矩形分成两半,找一个中间轴,轴上的每个点跑一边最短路更新所有的答案

然后把矩形分成两半,递归下去

代码

#include <bits/stdc++.h>
#define enter putchar('\n')
#define space putchar(' ')
#define pii pair<int,int>
#define fi first
#define se second
#define mp make_pair
#define pb push_back
#define eps 1e-8
//#define ivorysi
using namespace std;
typedef long long int64;
typedef double db;
template<class T>
void read(T &res) {
res = 0;T f = 1;char c = getchar();
while(c < '0' || c > '9') {
if(c == '-') f = -1;
c = getchar();
}
while(c >= '0' && c <= '9') {
res = res * 10 - '0' + c;
c = getchar();
}
res *= f;
}
template<class T>
void out(T x) {
if(x < 0) {x = -x;putchar('-');}
if(x >= 10) out(x / 10);
putchar('0' + x % 10);
}
int N,M,Q;
int id(int x,int y) {return (x - 1) * M + y;}
pii point(int s) {return mp((s - 1) / M + 1,(s - 1) % M + 1);}
struct qry_node {
int s,t,id;
}qry[100005],tmp[100005];
struct node {
int to,next,val;
}E[200005];
int head[20005],sumE;
int R[20005],C[20005],ans[100005],dis[20005];
bool vis[20005];
priority_queue<pii > que;
void add(int u,int v,int c) {
E[++sumE].to = v;
E[sumE].next = head[u];
E[sumE].val = c;
head[u] = sumE;
}
bool in_Matrix(int x,int X1,int Y1,int X2,int Y2) {
pii p = point(x);
return p.fi >= X1 && p.fi <= X2 && p.se >= Y1 && p.se <= Y2;
}
void Dijkstra(int st,int X1,int Y1,int X2,int Y2) {
for(int i = X1 ; i <= X2 ; ++i) {
for(int j = Y1 ; j <= Y2 ; ++j) {
dis[id(i,j)] = 0x7fffffff;
vis[id(i,j)] = 0;
}
}
dis[st] = 0;
que.push(mp(-dis[st],st));
while(!que.empty()) {
pii now = que.top();que.pop();
if(vis[now.se]) continue;
vis[now.se] = 1;
int u = now.se;
for(int i = head[u] ; i ; i = E[i].next) {
int v = E[i].to;
if(!vis[v] && in_Matrix(v,X1,Y1,X2,Y2) && dis[v] > dis[u] + E[i].val) {
dis[v] = dis[u] + E[i].val;
que.push(mp(-dis[v],v));
}
}
}
}
void update(int &x,int y) {
x = min(x,y);
}
void Solve(int l,int r,int X1,int Y1,int X2,int Y2) {
if(Y1 > Y2 || X1 > X2) return;
if(Y1 == Y2 && X1 == X2) return;
if(l > r) return;
if(X2 - X1 <= Y2 - Y1) {
int mid = (Y2 + Y1) >> 1;
for(int i = X1 ; i <= X2 ; ++i) {
Dijkstra(id(i,mid),X1,Y1,X2,Y2);
for(int k = l ; k <= r ; ++k) {
update(ans[qry[k].id],dis[qry[k].s] + dis[qry[k].t]);
}
}
int p = l - 1,m = l - 1;
for(int k = l ; k <= r ; ++k) {
if(in_Matrix(qry[k].s,X1,Y1,X2,mid - 1) && in_Matrix(qry[k].t,X1,Y1,X2,mid - 1)) {
tmp[++p] = qry[k];
}
}
m = p;
for(int k = l ; k <= r ; ++k) {
if(in_Matrix(qry[k].s,X1,mid + 1,X2,Y2) && in_Matrix(qry[k].t,X1,mid + 1,X2,Y2)) {
tmp[++p] = qry[k];
}
}
for(int i = l ; i <= p ; ++i) qry[i] = tmp[i];
Solve(l,m,X1,Y1,X2,mid - 1);
Solve(m + 1,p,X1,mid + 1,X2,Y2);
}
else {
int mid = (X1 + X2) >> 1;
for(int j = Y1 ; j <= Y2 ; ++j) {
Dijkstra(id(mid,j),X1,Y1,X2,Y2);
for(int k = l ; k <= r ; ++k) {
update(ans[qry[k].id],dis[qry[k].s] + dis[qry[k].t]);
}
}
int p = l - 1,m = l - 1;
for(int k = l ; k <= r ; ++k) {
if(in_Matrix(qry[k].s,X1,Y1,mid - 1,Y2) && in_Matrix(qry[k].t,X1,Y1,mid - 1,Y2)) {
tmp[++p] = qry[k];
}
}
m = p;
for(int k = l ; k <= r ; ++k) {
if(in_Matrix(qry[k].s,mid + 1,Y1,X2,Y2) && in_Matrix(qry[k].t,mid + 1,Y1,X2,Y2)) {
tmp[++p] = qry[k];
}
}
for(int i = l ; i <= p ; ++i) qry[i] = tmp[i];
Solve(l,m,X1,Y1,mid - 1,Y2);
Solve(m + 1,p,mid + 1,Y1,X2,Y2);
}
}
void Init() {
read(N);read(M);
for(int i = 1 ; i <= N ; ++i) {
for(int j = 1 ; j <= M - 1; ++j) {
read(R[id(i,j)]);
add(id(i,j),id(i,j + 1),R[id(i,j)]);
add(id(i,j + 1),id(i,j),R[id(i,j)]);
}
}
for(int i = 1 ; i <= N - 1 ; ++i) {
for(int j = 1 ; j <= M ; ++j) {
read(C[id(i,j)]);
add(id(i,j),id(i + 1,j),C[id(i,j)]);
add(id(i + 1,j),id(i,j),C[id(i,j)]);
}
}
read(Q);
int x,y;
for(int i = 1 ; i <= Q ; ++i) {
read(x);read(y);qry[i].s = id(x,y);
read(x);read(y);qry[i].t = id(x,y);
qry[i].id = i;
ans[i] = 0x7fffffff;
if(qry[i].s == qry[i].t) ans[i] = 0;
} }
int main() {
#ifdef ivorysi
freopen("f1.in","r",stdin);
#endif
Init();
Solve(1,Q,1,1,N,M);
for(int i = 1 ; i <= Q ; ++i) {out(ans[i]);enter;}
}

【LOJ】#2090. 「ZJOI2016」旅行者的更多相关文章

  1. @loj - 2090@ 「ZJOI2016」旅行者

    目录 @description@ @solution@ @accepted code@ @details@ @description@ 小 Y 来到了一个新的城市旅行.她发现了这个城市的布局是网格状的 ...

  2. 2090. 「ZJOI2016」旅行者 分治,最短路

    2090. 「ZJOI2016」旅行者 链接 loj 思路 \((l,mid)(mid+1,r)\).考虑跨过mid的贡献. 假设选的中间那条线的点为gzy,贡献为\(dis(x,gzy)+dis(g ...

  3. 「ZJOI2016」旅行者 解题报告

    「ZJOI2016」旅行者 对网格图进行分治. 每次从中间选一列,然后枚举每个这一列的格子作为起点跑最短路,进入子矩形时把询问划分一下,有点类似整体二分 至于复杂度么,我不会阿 Code: #incl ...

  4. loj2090 「ZJOI2016」旅行者

    分治+最短路,很套路的 #include <algorithm> #include <iostream> #include <cstring> #include & ...

  5. @loj - 2093@ 「ZJOI2016」线段树

    目录 @description@ @solution@ @accepted code@ @details@ @description@ 小 Yuuka 遇到了一个题目:有一个序列 a1,a2,..., ...

  6. @loj - 2092@ 「ZJOI2016」大森林

    目录 @description@ @solution@ @accepted code@ @details@ @description@ 小 Y 家里有一个大森林,里面有 n 棵树,编号从 1 到 n. ...

  7. @loj - 2091@ 「ZJOI2016」小星星

    目录 @description@ @solution@ @accepted code@ @details@ @description@ 小 Y 是一个心灵手巧的女孩子,她喜欢手工制作一些小饰品.她有 ...

  8. 「ZJOI2016」解题报告

    「ZJOI2016」解题报告 我大浙的省选题真是超级神仙--这套已经算是比较可做的了. 「ZJOI2016」旅行者 神仙分治题. 对于一个矩形,每次我们从最长边切开,最短边不会超过 \(\sqrt{n ...

  9. Loj #2192. 「SHOI2014」概率充电器

    Loj #2192. 「SHOI2014」概率充电器 题目描述 著名的电子产品品牌 SHOI 刚刚发布了引领世界潮流的下一代电子产品--概率充电器: 「采用全新纳米级加工技术,实现元件与导线能否通电完 ...

随机推荐

  1. bzoj1052

    Description 某人在山上种了N棵小树苗.冬天来了,温度急速下降,小树苗脆弱得不堪一击,于是树主人想用一些塑料薄 膜把这些小树遮盖起来,经过一番长久的思考,他决定用3个L*L的正方形塑料薄膜将 ...

  2. POJ 3159 Candies (图论,差分约束系统,最短路)

    POJ 3159 Candies (图论,差分约束系统,最短路) Description During the kindergarten days, flymouse was the monitor ...

  3. 洛谷P1155 双栈排序

    这题什么毒瘤......之前看一直没思路,然后心说写个暴搜看能有多少分,然后就A了??! 题意:给你一个n排列,求它们能不能通过双栈来完成排序.如果能输出最小字典序方案. [update]这里面加了一 ...

  4. 【洛谷P1522】牛的旅行

    题目大意:给定一个 N 个顶点的无向图,图中有若干联通块,现定义联通块的直径为该联通块中距离最远的两个点的距离,定义无向图的直径为这个图中所有联通块直径的最大值.现在在图上加一条边,使得两个本不连通的 ...

  5. 移动H5开发入门教程:12点webAPP前端开发经验

    如果你是一名移动H5前端开发人员,25学堂的小编认为下面的分享的12点webAPP前端开发经验是你必须掌握的基础知识点.算是一篇移动H5开发入门教程吧! 1. viewport:也就是可视区域.对于桌 ...

  6. Hadoop生态圈-Flume的组件之自定义拦截器(interceptor)

    Hadoop生态圈-Flume的组件之自定义拦截器(interceptor) 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 本篇博客只是举例了一个自定义拦截器的方法,测试字节传输速 ...

  7. keepalived 配置文件参数详解

    global_defs 全局配置vrrpd 1. vrrp_script添加一个周期性执行的脚本.脚本的退出状态码会被调用它的所有的VRRP Instance记录. 2. vrrp_sync_grou ...

  8. centos内存自动清理脚本及限制tomcat内存占用

    使用crontab定时每天自动清理系统内存 00 00 * * * /root/Cached.sh [root@localhost ~]# cat Cachec.sh #! /bin/bash# ca ...

  9. SPOJ 8222 NSUBSTR - Substrings

    http://www.spoj.com/problems/NSUBSTR/ 题意: F(x)定义为字符串S中所有长度为x的子串重复出现的最大次数 输出F[1]~F[len(S)] 用字符串S构建后缀自 ...

  10. Codeforces Round #540 Tanya and Candies 预处理

    http://codeforces.com/contest/1118/problem/B 题目大意,给你一个序列,删去一个数值之后,要求剩下序列奇数和偶数的和相同,问有多少种删法. 思路:预处理奇数和 ...