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; } /* */