描述
如下图所示,某市市区由M条南北向的大街和N条东西向的道路组成。其中由北向南第i条路和第i+1条路之间的距离是Bi (1 <= i < N),由西向东第i条街和第i+1条街之间的距离是Ai (1 <= i < M)。
小Ho现在位于第x条路和第y条街的交叉口,他的目的地是第p条路和第q条街的交叉口。由于连日降雨,城市中有K个交叉口积水太深不能通行。小Ho想知道到达目的地的最短路径的长度是多少。
输入
第一行包含两个整数N和M。(1 <= N, M <= 500)
第二行包含N-1个整数, B1, B2, B3, … BN-1。(1 <= Bi <= 100)
第三行包含M-1个整数, A1, A2, A3, … AM-1。(1 <= Ai <= 100)
第四行包含一个整数K,表示积水的交叉口的数目。 (0 <= K <= 30)
以下K行每行包含2个整数,X和Y,表示第X条路和第Y条街的交叉口积水。(1 <= X <= N, 1 <= Y <= M)
第K+5行包含一个整数Q,表示询问的数目。 (1 <= Q <= 10)
以下Q行每行包含4个整数x, y, p, q,表示小Ho的起止点。起止点保证不在积水的交叉口处。 (1 <= x, p <= N, 1 <= y, q <= M)
输出
对于每组询问,输出最短路的长度。如果小Ho不能到达目的地,输出-1。
样例输入
4 5
2 4 1
3 3 3 2
3
1 3
2 3
3 2
1
1 2 2 4
样例输出
24
之前的hiho一下..这个题spfa能AC,dfs或者bfs应该会超时吧,题给的范围很大,这题基本上板子题,有趣的是把这个图中的点转化成点之间的路径,这一步稍微有点麻烦=w=
题意:
告诉长宽的地图与街道的长度,地图中有些点不能走,再告诉起点终点,求最短路.
想法:
因为告诉的不是一个点与另一个点的长度,所以需要将这个二维图中的点稍微提取出来用一维存一下,完了后直接spfa就能解了=w=
#include <iostream>
#include <queue>
#include <cstring>
#include <cstdio>
using namespace std;
#define INF 0x3f3f3f3f
#define ll long long
ll dir[4][2] = {1, 0, 0, 1, -1, 0, 0, -1};
struct Node
{
ll to;
ll length;
};
vector<Node>V[250050];
bool visit[250050];
ll d[250050];
int main()
{
ll n;
ll m;
ll i;
ll j;
ll k;
scanf("%lld%lld", &n, &m);
//cin >> n >> m;
memset(visit, false, sizeof(visit));
ll B[505];
ll A[505];
for(i = 1; i < n; i++)
{
scanf("%lld", &B[i]);
//cin >> B[i];
}
for(i = 1; i < m; i++)
{
scanf("%lld", &A[i]);
//cin >> A[i];
}
scanf("%lld", &k);
//cin >> k;
ll x;
ll y;
while(k--)
{
scanf("%lld%lld", &x, &y);
ll tmp = (x-1)*m+y;
visit[tmp] = true;
}
for(i = 1; i <= n; i++)
{
for(j = 1; j <= m; j++)
{
for(k = 0; k < 4; k++)//重点就是这一块,将图中每个点的情况转化成4条路径来存
{
if(visit[(i-1)*m+j])
{
continue;
}
ll ny = i+dir[k][0];
ll nx = j+dir[k][1];
if(nx>0&&ny>0&&nx<=m&&ny<=n)
{
Node N;
N.to = (ny-1)*m+nx;
if(visit[N.to])
{
continue;
}
if(k==0)
{
N.length = B[i];
}
if(k==1)
{
N.length = A[j];
}
if(k==2)
{
N.length = B[ny];
}
if(k==3)
{
N.length = A[nx];
}
V[(i-1)*m+j].push_back(N);
}
}
}
}
ll q;
scanf("%lld", &q);
//cin >> q;
while(q--)
{
queue<ll>Q;
scanf("%lld%lld", &x, &y);
ll s = (x-1)*m+y;
scanf("%lld%lld", &x, &y);
ll e = (x-1)*m+y;
memset(d, INF, sizeof(d));
memset(visit, false, sizeof(visit));
Q.push(s);
d[s] = 0;
visit[s] = true;
while(!Q.empty())
{
ll now = Q.front();
Q.pop();
visit[now] = false;
for(i = 0; i < V[now].size(); i++)
{
ll tmp = V[now][i].to;
if(V[now][i].length+d[now] < d[tmp])
{
d[tmp] = V[now][i].length+d[now];
if(!visit[tmp])
{
Q.push(tmp);
visit[tmp] = true;
}
}
}
}
if(d[e] >= INF)
{
printf("-1\n");
}
else
{
printf("%lld\n", d[e]);
}
}
return 0;
}