### 输出

#include <iostream>
#include <stdio.h>
#include <vector>
#include <map>
#include <cmath>
#include <set>
#include <queue>
#include <algorithm>
using namespace std;

#define MK make_pair

const int inf = 1000000007;
const int N = 1005;
const int M = 1005;

int n,m,block_num;
int dis_n[N],dis_m[M]；
int next_l[M],next_r[M],next_l_n[N],next_r_n[N]; // 对图进行压缩

map<int,int> mp; //对图进行压缩使用的数据结构
map<int,int>mp_n;<span style="font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;">//对图进行压缩使用的数据结构</span>

set<pair<int,int> > st;  // 保存积水交叉口

int dis[N][M];//最短路径
int start_n,start_m,end_n,end_m;
int sum_m[M],sum_n[M];  //对距离求和，进行预处理


//判断是否加入队列中
void inline judge(queue<pair<int,int> >& que,int x,int y,int new_dis,int add_dis)
{
if(1<=x && x <= n && 1 <= y && y <= m && st.find(MK(x,y)) == st.end())
{
{
if(x != end_n || y != end_m)
que.push(MK(x,y));
}
}
}

int SPFA()
{
//对图进行压缩，找上下左右的邻居
mp[start_m] += 1;
mp[end_m] += 1;

mp_n[start_n] += 1;
mp_n[end_n] += 1;

int pre_num = 0,current_num;
map<int,int>::iterator it = mp.begin();
it++;
for(;it != mp.end();it++)
{
current_num = it->first;
next_r[pre_num] = current_num;
next_l[current_num] = pre_num;

pre_num = current_num;
}

pre_num = 0;
it = mp_n.begin();
it++;
for(;it != mp_n.end();it++)
{
current_num = it->first;
next_r_n[pre_num] = current_num;
next_l_n[current_num] = pre_num;
pre_num = current_num;
}

dis[start_n][start_m] = 0;
queue<pair<int,int> >que;
que.push(MK(start_n,start_m));

int x,y;
pair<int,int> node;
while(!que.empty())
{
node = que.front();
que.pop();
//cout << node.first << ' ' << node.second << endl;
<span style="white-space:pre">		</span>// 下面的点
x = next_r_n[node.first];
y = node.second;
judge(que,x,y,dis[node.first][node.second],sum_n[x - 1] - sum_n[node.first - 1]);
<span style="white-space:pre">		</span>//上面的点
x = next_l_n[node.first];
y = node.second;
judge(que,x,y,dis[node.first][node.second],sum_n[node.first - 1] - sum_n[x - 1]);
<span style="white-space:pre">		</span>//右面的点
x = node.first;
y = next_r[node.second];
judge(que,x,y,dis[node.first][node.second],sum_m[y - 1] - sum_m[node.second - 1]);
<span style="white-space:pre">		</span>//左面的点
x = node.first;
y = next_l[node.second];
judge(que,x,y,dis[node.first][node.second],sum_m[node.second - 1] - sum_m[y - 1]);

}
<span style="white-space:pre">	</span>//删除查询点，避免查询过多的情况下，压缩图没什么效果
mp[start_m] -= 1;
mp[end_m] -= 1;
if(mp[start_m] == 0)
mp.erase(start_m);

if(mp[end_m] == 0)
mp.erase(end_m);

mp_n[start_n] -= 1;
mp_n[end_n] -= 1;
if(mp_n[start_n] == 0)
mp_n.erase(start_n);

if(mp_n[end_n] == 0)
mp_n.erase(end_n);

if(dis[end_n][end_m] != inf)
return dis[end_n][end_m];
return -1;
}
int main()
{
scanf("%d %d",&n,&m);
sum_n[0] = 0;
for(int i = 1;i<n;i++)
{
scanf("%d",dis_n + i);
sum_n[i] = sum_n[i -1] + dis_n[i];
}
sum_m[0] = 0;
for(int i = 1;i<m;i++)
{
scanf("%d",dis_m + i);
sum_m[i] = sum_m[i -1] + dis_m[i];
}

scanf("%d",&block_num);
int x,y;
for(int i = 0;i<block_num;i++)
{
scanf("%d %d",&x,&y);
st.insert(MK(x,y));
mp[y] = 1;
if(y >1)
mp[y - 1] = 1;
if(y < m)
mp[y + 1] = 1;

mp_n[x] = 1;
if(x >1)
mp_n[x - 1] = 1;
if(x < n)
mp_n[x + 1] = 1;
}
<span style="white-space:pre">	</span>// 加入边界，使程序好处理
mp[0] = 1;
mp[m + 1] = 1;
mp_n[0] = 1;
mp_n[n + 1] = 1;
int q;
scanf("%d",&q);
for(int i = 0;i<q;i++)
{
scanf("%d %d %d %d",&start_n,&start_m,&end_n,&end_m);
if(start_m > end_m)
{
swap(start_n,end_n);
swap(start_m,end_m);
}

for(int j = 0;j<=n;j++)
for(int k = 0;k<=m;k++)
dis[j][k] = inf;
printf("%d\n",SPFA());
}
return 0;
}

#### hihoCoder简单问题合集

2018-03-31 20:21:10

#### 数位DP 浅谈(hihocoder 1033:交错和)

2015-02-03 13:16:36

#### ACM解题总结——HihoCoder1199 (微软笔试题)

2016-08-03 21:25:35

#### hiho一下 第四周 Hihocoder #1036 : Trie图

2014-08-05 01:16:55

#### hihocoder刷题之路_1

2018-03-11 22:15:21

#### 网易2018 Android实习生在线编程笔试题

2018-03-27 22:28:21

#### hihoCoder 题目答案

2017-10-04 16:10:23

#### 【八中测试】跑马圈地(HihoCoder - 1042)

2018-03-12 13:35:36

#### 牛客网 Wannafly交流赛1 D 迷宫2 （思维+bfs）

2018-03-03 11:03:35

#### 刘符文的简书 写的不错 支持下

2018-02-26 15:09:34

hihocoder