双关键最短路。。。看了题解才会做的。。。
#include <iostream> #include <queue> #include <stack> #include <map> #include <set> #include <bitset> #include <cstdio> #include <algorithm> #include <cstring> #include <climits> #include <cstdlib> #include <cmath> #include <time.h> #define maxn 505 #define maxm 2500005 #define eps 1e-12 #define mod 998244353 #define INF 0x3f3f3f3f #define PI (acos(-1.0)) #define lowbit(x) (x&(-x)) #define mp make_pair //#define ls o<<1 //#define rs o<<1 | 1 //#define lson o<<1, L, mid //#define rson o<<1 | 1, mid+1, R #define pii pair<int, int> typedef long long LL; typedef unsigned long long ULL; //typedef int LL; using namespace std; LL qpow(LL a, LL b){LL res=1,base=a;while(b){if(b%2)res=res*base;base=base*base;b/=2;}return res;} LL powmod(LL a, LL b){LL res=1,base=a;while(b){if(b%2)res=res*base%mod;base=base*base%mod;b/=2;}return res;} // head struct Edge { int vx, vy, w, t; Edge *next; }*H[maxn][maxn], E[maxm], *edges; typedef pair<pii, pii> node; pii dis[maxn][maxn]; int sx, sy, tx, ty; int dir[4][2] = {{0, 1}, {0, -1}, {1, 0}, {-1, 0}}; char g[maxn][maxn]; int n, m; pii operator + (pii& a, pii& b) { return mp(a.first + b.first, a.second + b.second); } void addedges(int ux, int uy, int vx, int vy, int w, int t) { edges->vx = vx; edges->vy = vy; edges->w = w, edges->t = t; edges->next = H[ux][uy]; H[ux][uy] = edges++; } void init() { edges = E; memset(H, 0, sizeof H); memset(g, '#', sizeof g); } bool check(int x, int y) { if(x > n || x <= 0 || y > m || y <= 0) return false; if(g[x][y] == '#') return false; return true; } void bfs() { priority_queue<node, vector<node>, greater<node> > q; q.push(node(mp(0, 0), mp(sx, sy))); memset(dis, 0x7f, sizeof dis); dis[sx][sy] = mp(0, 0); while(!q.empty()) { int x = q.top().second.first, y = q.top().second.second; if(x == tx && y == ty) break; q.pop(); for(Edge *e = H[x][y]; e; e = e->next) { int vx = e->vx, vy = e->vy, w = e->w; if(g[vx][vy] >= 'a' && g[vx][vy] <= 'z') w += g[vx][vy] - 'a' + 1; pii cost = mp(w, e->t); if(dis[vx][vy] > dis[x][y] + cost) { dis[vx][vy] = dis[x][y] + cost; q.push(node(dis[vx][vy], mp(vx, vy))); } } } printf("%d %d\n", dis[tx][ty].first, dis[tx][ty].second); } void work() { scanf("%d%d", &n, &m); scanf("%d%d%d%d", &sx, &sy, &tx, &ty); for(int i = 1; i <= n; i++) scanf("%s", g[i]+1); for(int i = 1; i <= n; i++) for(int j = 1; j <= m; j++) if(g[i][j] != '#' && !isupper(g[i][j])) { for(int k1 = 0; k1 < 4; k1++) { int x1 = i + dir[k1][0]; int y1 = j + dir[k1][1]; if(!check(x1, y1) || isupper(g[x1][y1])) continue; int cost = 0; for(int k2 = 0; k2 < 4; k2++) { int x2 = x1 + dir[k2][0]; int y2 = y1 + dir[k2][1]; if(!check(x2, y2)) continue; if(g[x2][y2] >= 'A' && g[x2][y2] <= 'Z') cost += g[x2][y2] - 'A' + 1; } addedges(i, j, x1, y1, cost, 1); } } for(int i = 1; i <= n; i++) for(int j = 1; j <= m; j++) if(g[i][j] >= 'A' && g[i][j] <= 'Z') { for(int k1 = 0; k1 < 4; k1++) { int x1 = i + dir[k1][0]; int y1 = j + dir[k1][1]; if(!check(x1, y1)) continue; for(int k2 = 0; k2 < 4; k2++) if(k1 != k2) { int x2 = i + dir[k2][0]; int y2 = j + dir[k2][1]; int cost = 0; if(!check(x2, y2)) continue; for(int k3 = 0; k3 < 4; k3++) { int x = x2 + dir[k3][0]; int y = y2 + dir[k3][1]; if(!check(x, y) || abs(x - x1) + abs(y - y1) <= 1) continue; if(g[x][y] >= 'A' && g[x][y] <= 'Z') cost += g[x][y] - 'A' + 1; } addedges(x1, y1, x2, y2, cost, 2); } } } bfs(); } int main() { int _; scanf("%d", &_); while(_--) init(), work(); return 0; }