首页 > 代码库 > HDU 5040 Instrusive(最短路)

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\n", cas, spfa());108     }109     return 0;110 }111 /*112 111113 3114 #S#115 WM.116 #WT117 */
View Code

 

HDU 5040 Instrusive(最短路)