標籤:
Easy Graph Problem?
題目抽象:給你一個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 + 優先隊列