积水的城市(SPFA)

此处传送门

描述

如下图所示,某市市区由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;
}

猜你喜欢

转载自blog.csdn.net/xiaotudeluobo/article/details/79177695