HDU 5040 Instrusive(最短路)
题目 : http://acm.hdu.edu.cn/showproblem.php?pid=5040
题意 : 从'M' 到 'T' 最短路程,每次只能走四个方向,并且有一些摄像头每个时间点都会转变下方向(初始方向给出).你有一个box,你在没有罩box的情况下不能被照到,可以在点上等待,也可以罩着box走(时间会慢成3个单位)。
思路 : 就是一个最短路问题,只要算出在当前时间点u->v最多要花多时间才能到就行了(最多是3),用spfa跑。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
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 111 113 3 114 #S# 115 WM. 116 #WT 117 */