HDU 5040 Instrusive(最短路)

题目 : http://acm.hdu.edu.cn/showproblem.php?pid=5040

题意 : 从'M' 到  'T' 最短路程,每次只能走四个方向,并且有一些摄像头每个时间点都会转变下方向(初始方向给出).你有一个box,你在没有罩box的情况下不能被照到,可以在点上等待,也可以罩着box走(时间会慢成3个单位)。

思路 : 就是一个最短路问题,只要算出在当前时间点u->v最多要花多时间才能到就行了(最多是3),用spfa跑。

  1 #include <cstdio>
  2 #include <cstring>
  3 #include <algorithm>
  4 #include <vector>
  5 #include <queue>
  6 
  7 using namespace std;
  8 typedef pair<int, int> PII;
  9 const int MAXN = 505;
 10 const int dir[4][2] = {-1, 0, 0, 1, 1, 0, 0, -1}; // N E S W
 11 const int INF = 0x3f3f3f3f;
 12 
 13 struct A {
 14     int x, y;
 15     A() {}
 16     A(int a, int b):x(a), y(b) {}
 17 };
 18 
 19 char maze[MAXN][MAXN];
 20 int dis[MAXN][MAXN];
 21 int vis[MAXN][MAXN];
 22 int n;
 23 int sx, sy, ex, ey;
 24 
 25 PII change(int x, int y, int tim) {
 26     int add;
 27     if (maze[x][y] == 'N') add = 0;
 28     if (maze[x][y] == 'E') add = 1;
 29     if (maze[x][y] == 'S') add = 2;
 30     if (maze[x][y] == 'W') add = 3;
 31     add = (add + tim) % 4;
 32     return make_pair(x + dir[add][0], y + dir[add][1]);
 33 }
 34 int isok(int x, int y, int tim) {
 35     if (maze[x][y] == 'N' || maze[x][y] == 'S' || maze[x][y] == 'E' || maze[x][y] == 'W') {
 36         return 0;
 37     }
 38     for (int i = 0; i < 4; i++) {
 39         int X = x + dir[i][0];
 40         int Y = y + dir[i][1];
 41         if (maze[X][Y] == 'N' || maze[X][Y] == 'S' || maze[X][Y] == 'E' || maze[X][Y] == 'W') {
 42             PII tmp = change(X, Y, tim);
 43             if (tmp.first == x && tmp.second == y) return 0;
 44         }
 45     }
 46     return 1;
 47 }
 48 int calc(int nx, int ny, int nex, int ney, int tim) {
 49     for (int i = 0; i <= 2; i++) {
 50         if (isok(nx, ny, tim + i) && isok(nex, ney, tim + i)) {
 51             return i + 1;
 52         }
 53     }
 54     return 3;
 55 }
 56 
 57 int spfa() {
 58     queue<A> Q;
 59     memset(vis, 0, sizeof(vis));
 60     vis[sx][sy] = 1;
 61     Q.push(A(sx, sy));
 62     memset(dis, INF, sizeof(dis));
 63     dis[sx][sy] = 0;
 64     while (!Q.empty()) {
 65         A e = Q.front(); Q.pop();
 66         int X = e.x;
 67         int Y = e.y;
 68         int now = dis[X][Y];
 69         vis[X][Y] = 0;
 70         for (int i = 0; i < 4; i++) {
 71             int x = X + dir[i][0];
 72             int y = Y + dir[i][1];
 73             if (x <= 0 || y <= 0 || x > n || y > n || maze[x][y] == '#') {
 74                 continue;
 75             }
 76             int d = calc(X, Y, x, y, now);
 77             if (dis[x][y] > now + d) {
 78                 dis[x][y] = now + d;
 79                 if (!vis[x][y]) {
 80                     vis[x][y] = 1;
 81                     Q.push(A(x, y));
 82                 }
 83             }
 84         }
 85     }
 86     return dis[ex][ey] == INF ? -1 : dis[ex][ey];
 87 }
 88 
 89 int main() {
 90     int T;
 91     scanf("%d", &T);
 92     for (int cas = 1; cas <= T; cas++) {
 93         scanf("%d", &n);
 94         for (int i = 1; i <= n; i++) {
 95             scanf("%s", maze[i] + 1);
 96         }
 97         for (int i = 1; i <= n; i++) {
 98             for (int j = 1; j <= n; j++) {
 99                 if (maze[i][j] == 'M') {
100                     sx = i; sy = j;
101                 }
102                 if (maze[i][j] == 'T') {
103                     ex = i; ey = j;
104                 }
105             }
106         }
107         printf("Case #%d: %d
", cas, spfa());
108     }
109     return 0;
110 }
111 /*
112 111
113 3
114 #S#
115 WM.
116 #WT
117 */
View Code
原文地址:https://www.cnblogs.com/danceonly/p/3993061.html