CF1301F Super Jaber
https://www.luogu.com.cn/problem/CF1301F
因为 k k k很小,所以我们可以记录 f [ x ] [ y ] [ k ] f[x][y][k] f[x][y][k]表示从 ( x , y ) (x,y) (x,y)出发,走到颜色为 k k k的最短距离
建反图跑bfs即可
然后简单分类讨论一下即可
写到一半确切感觉到自己基础不扎实
#include<bits/stdc++.h>
#define N 1000050
using namespace std;
inline int read() {
int x = 0; char ch = getchar();
for(; ch < '0' || ch > '9'; ) ch = getchar();
for(; ch >= '0' && ch <= '9'; ) x = (x << 3) + (x <<1) + (ch - '0'), ch = getchar();
return x;
}
vector<int> g[N], a[N];
void insert(int u, int v) {
g[u].push_back(v), g[v].push_back(u);
}
int n, m, c, qq;
short dis[42][N], col[N], visc[42];
inline int id(int x, int y) {
return (x - 1) * m + y;
}
queue<int> q;
void dfs(int X) {
for(int i = 1; i <= n * m; i ++)
dis[X][i] = -1;
for(int i = 1; i <= c; i ++) visc[i] = 0;
visc[X] = 1;
for(int x : a[X]) dis[X][x] = 0, q.push(x);
int gs = 0;
while(q.size()) {
int u = q.front(); q.pop();
if(!visc[col[u]])
for(int v : a[col[u]]) if(dis[X][v] == -1) {
dis[X][v] = dis[X][u] + 1;
q.push(v);
}
visc[col[u]] = 1;
for(int v : g[u]) if(dis[X][v] == -1) {
dis[X][v] = dis[X][u] + 1;
q.push(v);
}
}
}
int main() {
n = read(), m = read(), c = read();
for(int i = 1; i <= n; i ++)
for(int j = 1; j <= m; j ++) {
int x;
x = read();
col[id(i, j)] = x;
a[x].push_back(id(i, j));
}
for(int i = 1; i <= n; i ++)
for(int j = 1; j <= m; j ++) {
if(i > 1) insert(id(i - 1, j), id(i, j));
if(j > 1) insert(id(i, j - 1), id(i, j));
}
for(int k = 1; k <= c; k ++) if(a[k].size()) {
dfs(k);
}
qq = read();
while(qq --) {
int x, y, xx, yy;
x = read(), y = read(), xx = read(), yy = read();
int ans = abs(x - xx) + abs(y - yy);
for(int k = 1; k <= c; k ++) if(a[k].size()) ans = min(ans, dis[k][id(x, y)] + dis[k][id(xx, yy)] + 1);
printf("%d\n", ans);
}
return 0;
}