ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

[2020CCPC威海B] Labyrinth - 结论,BFS

2020-10-31 20:03:20  阅读:300  来源: 互联网

标签:BFS ny Labyrinth holes nx 2020CCPC int que 障碍物


Description

给定一张 \(n \times m\) 的棋盘,上面有 \(k\) 个障碍物,有 \(q\) 次询问,每次给定两个点 \((x_1,y_1),\ (x_2,y_2)\),问这两点之间的最短路径长度。\(n\cdot m \le 2 \times 10^5, k \le 42, q \le 10^5\)

Solution

对于 \((x_1,y_1),\ (x_2,y_2)\) 两点构成的最短路径,如果大于忽略障碍物时的曼哈顿距离,则一定有一条贴着障碍物的路径与它等长。

所谓贴着障碍物,就是路径上至少存在一个点,是障碍物的邻居。

因此,如果矩形 \((x_1,y_1) - (x_2,y_2)\) 中没有障碍物,我们就直接用曼哈顿距离;否则,找到一个障碍物的邻居点 \((x_t,y_t)\),使得路径 \((x_1,y_1) \to (x_t,y_t) \to (x_2,y_2)\) 最短。

判断矩形中是否有障碍物显然可以暴力实现。

求最短距离,只需要预处理每一个障碍物邻居点到棋盘上所有点的最短距离即可。

#include <bits/stdc++.h>
using namespace std;

const int N = 400005;
const int inf = 0x3f3f3f3f;
const int dx[4] = {1, -1, 0, 0};
const int dy[4] = {0, 0, -1, 1};

set<pair<int, int>> s;
int *dis[50][4][N];

vector<pair<int, int>> holes;

int n, m, k, q;

struct Item
{
    int x, y, d;
};

int check(int x1, int y1, int x2, int y2)
{
    if (x1 > x2)
        swap(x1, x2);
    if (y1 > y2)
        swap(y1, y2);
    for (auto hole : holes)
    {
        int nx = hole.first, ny = hole.second;
        if (x1 <= nx && nx <= x2 && y1 <= ny && ny <= y2)
            return true;
    }
    return false;
}

signed main()
{
    ios::sync_with_stdio(false);
    cin >> n >> m >> k >> q;
    for (int i = 1; i <= k; i++)
    {
        int t1, t2;
        cin >> t1 >> t2;
        holes.push_back({t1, t2});
        s.insert({t1, t2});
    }
    for (int holeId = 0; holeId < holes.size(); holeId++)
    {
        auto hole = holes[holeId];
        int x = hole.first, y = hole.second;
        for (int pos = 0; pos < 4; pos++)
        {
            int nx = x + dx[pos], ny = y + dy[pos];
            if (nx >= 1 && nx <= n && ny >= 1 && ny <= m)
            {
                for (int i = 0; i <= n + 1; i++)
                {
                    dis[holeId][pos][i] = new int[m + 5];
                    for (int j = 0; j <= m + 1; j++)
                        dis[holeId][pos][i][j] = inf;
                }
                if (s.find({nx, ny}) == s.end())
                {
                    queue<Item> que;
                    que.push({nx, ny, 0});
                    dis[holeId][pos][nx][ny] = 0;
                    while (que.size())
                    {
                        int nx = que.front().x, ny = que.front().y, nd = que.front().d;
                        que.pop();
                        for (int p = 0; p < 4; p++)
                        {
                            int tx = nx + dx[p], ty = ny + dy[p], td = nd + 1;
                            if (tx >= 1 && tx <= n && ty >= 1 && ty <= m && s.find({tx, ty}) == s.end()) if (dis[holeId][pos][tx][ty] == inf)
                            {
                                dis[holeId][pos][tx][ty] = td;
                                que.push({tx, ty, td});
                            }
                        }
                    }
                }
            }
        }
    }
    for (int t = 1; t <= q; t++)
    {
        int x1, y1, x2, y2;
        cin >> x1 >> y1 >> x2 >> y2;
        if (check(x1, y1, x2, y2))
        {
            int ans = inf;
            for (int i = 0; i < k; i++)
            {
                for (int j = 0; j < 4; j++)
                {
                    int nx = holes[i].first + dx[j], ny = holes[i].second + dy[j];
                    if (1 <= nx && nx <= n && 1 <= ny && ny <= m)
                    {
                        ans = min(ans, dis[i][j][x1][y1] + dis[i][j][x2][y2]);
                    }
                }
            }
            if (ans < inf)
                cout << ans << endl;
            else
                cout << -1 << endl;
        }
        else
            cout << abs(x1 - x2) + abs(y1 - y2) << endl;
    }
    return 0;
}

标签:BFS,ny,Labyrinth,holes,nx,2020CCPC,int,que,障碍物
来源: https://www.cnblogs.com/mollnn/p/13907295.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有