标签:
题目抽象:给你一个n * m 的矩阵.每个格子是数字或者障碍物‘*‘. 第一问:从起点到终点的最短路.第二问:要求相同的方向不能连续走两次,也就是每到达一个格子,需要改变方向.问最短路. 不过不存在就输出-1.
分析:可以直接bfs搜索.第一问有一个minv[MS][MS]数组记录到达(i,j)的最短距离.第二问用flag[MS][MS][4]及记录(i,j)格子k方向是否走过.
由于2<=n,m<=500,范围较大.所以需要优先队列优化. 不然超时.
1 #include <cstdio> 2 #include <algorithm> 3 #include <queue> 4 using namespace std; 5 typedef long long LL; 6 const int INF = 0X5FFFFF; 7 const int MS = 505; 8 9 struct node { 10 int x, y, dir, cost; 11 bool operator < (const node & a) const { 12 return cost > a.cost; 13 } 14 }; 15 int pic[MS][MS]; 16 int dir[4][2] = {0,1,1,0,0,-1,-1,0}; 17 int flag[MS][MS][4]; 18 int minv[MS][MS]; 19 20 int n, m, r1, c1, r2, c2; 21 int kase = 1; 22 node s,t; 23 24 void bfs1() { 25 minv[r1][c1] = pic[r1][c1]; 26 s.x = r1; 27 s.y = c1; 28 s.cost = pic[r1][c1]; 29 priority_queue<node> que; 30 que.push(s); 31 while (!que.empty()) { 32 s = que.top(); 33 que.pop(); 34 for (int i = 0; i < 4; i++) { 35 int x = s.x + dir[i][0]; 36 int y = s.y + dir[i][1]; 37 if (x > 0 && x <= n && y > 0 && y <= m && pic[x][y]) { 38 t.x = x; 39 t.y = y; 40 t.cost = s.cost + pic[x][y]; 41 if (x == r2 && y == c2) { 42 printf(" %d", t.cost); 43 return ; 44 } 45 if (t.cost < minv[x][y]) { 46 minv[x][y] = t.cost; 47 que.push(t); 48 } 49 } 50 } 51 } 52 printf(" -1"); 53 } 54 55 void bfs2() { 56 s.x = r1; 57 s.y = c1; 58 s.cost = pic[r1][c1]; 59 priority_queue<node> que; 60 for (int i = 0; i < 4; i++) { 61 flag[r1][c1][i] = 1; 62 int x = s.x + dir[i][0]; 63 int y = s.y + dir[i][1]; 64 if (x > 0 && x <= n && y > 0 && y <= m && pic[x][y]) { 65 flag[x][y][i] = 1; 66 t.x = x; 67 t.y = y; 68 t.cost = s.cost + pic[x][y]; 69 t.dir = i; 70 que.push(t); 71 } 72 } 73 while (!que.empty()) { 74 s = que.top(); 75 que.pop(); 76 for (int i = 0; i < 4; i++) { 77 if (i == s.dir) 78 continue; 79 t.x = s.x + dir[i][0]; 80 t.y = s.y + dir[i][1]; 81 if (t.x > 0 && t.x <= n && t.y > 0 && t.y <= m && pic[t.x][t.y]) { 82 t.cost = s.cost + pic[t.x][t.y]; 83 t.dir = i; 84 if (t.x == r2 && t.y == c2) { 85 printf(" %d",t.cost); 86 return ; 87 } 88 if (flag[t.x][t.y][t.dir] == 0) { 89 flag[t.x][t.y][t.dir] = 1; 90 que.push(t); 91 } 92 } 93 94 } 95 } 96 printf(" -1"); 97 } 98 99 int main() { 100 char str[MS]; 101 while (scanf("%d%d%d%d%d%d", &n, &m, &r1, &c1, &r2, &c2) != EOF) { 102 for (int i = 1; i <= n; i++) 103 for (int j = 1; j <= m; j++) { 104 scanf("%s", str); 105 if (str[0] == ‘*‘) { 106 pic[i][j] = 0; 107 } 108 else { 109 sscanf(str, "%d", &pic[i][j]); // 初始化图 110 } 111 minv[i][j] = INF; // (i,j) 最小花费初始化 112 for (int k = 0; k < 4; k++) 113 flag[i][j][k] = 0; // (i,j) 四个方向初始化 114 } 115 printf("Case %d:",kase++); 116 bfs1(); 117 bfs2(); 118 printf("\n"); 119 } 120 return 0; 121 }
Easy Graph Problem?(一道简单图论题?) bfs + 优先队列
标签:
原文地址:http://www.cnblogs.com/hutaishi/p/4772012.html