Codeforces - 1301F - Super Jaber/AtCoder Beginner Contest 184E Third Avenue (多传送门bfs搜索问题)

ABC184E Third Avenue题目大意:

这个题是好久之前写的再简单说一下, 这个题算是1301F的一个弱化版吧

给你一个矩阵,给定起始点和终止点的坐标,然后矩阵中还有26个字母,相同字母可以相互传送

求起始点到终点的最短时间

题目思路:

直接从起点开始bfs,每次搜索到一个字母的时候的,假如说是第一次搜索到这个字母,那么我把这个字母能传送到的位置的

最短时间全给更新一遍

1301F-Super Jaber:

这个题目不同于上面题目的地方在,给你Q次询问,每次询问给出起点和终点,求最短时间

传送门的种类数<=40

共同点都是传送门的种类数少


我们可以设dis[k][i][j]表示从i到j通过k传送最短的时间

那我们需要预处理出通过k传送的所有的点对的最短距离

只需要对每种传送门进行一次bfs就可以得到答案

 

CODE:

// Problem: F. Super Jaber
// Contest: Codeforces - Codeforces Round #619 (Div. 2)
// URL: https://codeforces.com/contest/1301/problem/F
// Memory Limit: 256 MB
// Time Limit: 5000 ms
//
// Powered by CP Editor (https://cpeditor.org)

#include <algorithm>
#include <cctype>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <ctime>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <sstream>
#include <string>
#include <vector>
using namespace std;
typedef long long ll;
typedef pair<int, int> PII;
typedef unsigned long long ull;
const int inf = 0x3f3f3f3f;
const int maxn = 2e5 + 7;
const ll mod = 1e9 + 7;

#define pb push_back
#define debug(x) cout << #x << ":" << x << endl;
#define mst(x, a) memset(x, a, sizeof(x))
#define rep(i, a, b) for (int i = (a); i <= (b); ++i)
#define dep(i, a, b) for (int i = (a); i >= (b); --i)

inline ll read() {
    ll x = 0;
    bool f = 0;
    char ch = getchar();
    while (ch < '0' || '9' < ch)
        f |= ch == '-', ch = getchar();
    while ('0' <= ch && ch <= '9')
        x = x * 10 + ch - '0', ch = getchar();
    return f ? -x : x;
}

void out(ll x) {
    int stackk[20];
    if (x < 0) {
        putchar('-');
        x = -x;
    }
    if (!x) {
        putchar('0');
        return;
    }
    int top = 0;
    while (x)
        stackk[++top] = x % 10, x /= 10;
    while (top)
        putchar(stackk[top--] + '0');
}
ll qpow(ll a, ll b) {
    ll ans = 1;
    while (b) {
        if (b & 1)
            ans = ans * a % mod;
        a = a * a % mod;
        b >>= 1;
    }
    return ans;
}
int n, m, c[1002][1002], qq, k;
vector<PII> v[42];
int dis[42][1002][1002];
int vis[1002][1002], vi[44];
int dx[4] = {1, 0, -1, 0};
int dy[4] = {0, 1, 0, -1};
void bfs(int num) {
    mst(vis, 0);
    queue<PII> q;
    for (auto fr : v[num]) {
        int x = fr.first;
        int y = fr.second;
        dis[num][x][y] = 0;
        vis[x][y] = 1;
        q.push({x, y});
    }
    mst(vi, 0);
    vi[num] = 1;
    while (q.size()) {
        auto fr = q.front();
        q.pop();
        int x1 = fr.first;
        int y1 = fr.second;

        for (int i = 0; i < 4; i++) {
            int x2 = x1 + dx[i];
            int y2 = y1 + dy[i];
            if (x2 < 1 || x2 > n || y1 < 1 || y1 > m)
                continue;
            if (dis[num][x2][y2] > dis[num][x1][y1] + 1) {
                q.push({x2, y2});
                dis[num][x2][y2] = dis[num][x1][y1] + 1;
            }
        }

        if (vi[c[x1][y1]]==0) {
            vi[c[x1][y1]] = 1;
            for (auto t : v[c[x1][y1]]) {
                int x2 = t.first;
                int y2 = t.second;
                if (dis[num][x2][y2] > dis[num][x1][y1] + 1) {
                    q.push({x2, y2});
                    dis[num][x2][y2] = dis[num][x1][y1] + 1;
                }
            }
        }
    }
}
int main() {
    // ios::sync_with_stdio(false);
    n = read(), m = read(), k = read();
    for (int i = 1; i <= n; i++) {
        for (int j = 1; j <= m; j++) {
            c[i][j] = read();
            v[c[i][j]].push_back({i, j});
        }
    }
    mst(dis, inf);
    for (int i = 1; i <= k; i++)
        bfs(i);
    qq = read();
    while (qq--) {
        int x1, y1, x2, y2;
        x1 = read(), y1 = read(), x2 = read(), y2 = read();
        int ans = abs(x2 - x1) + abs(y1 - y2);
        rep(i, 1, k) ans = min(ans, dis[i][x1][y1] + dis[i][x2][y2] + 1);
        out(ans);
        puts("");
    }
    return 0;
}
/*


*/
View Code

 

posted @ 2021-05-02 16:04  UpMing  阅读(78)  评论(0编辑  收藏  举报