电路维修
这题。。。转成图论来做。
是这样的:对于每个方格,连接它已经连通的两个点,边权为0,另外两个点边权为1,代表转了一次。
然后求左上到右下的最短路即可。
然后SPFA就很优秀的T了。
正解:
01最短路 -> 双向BFS
对于每一个抵达的点,如果边权为1就放在最后,边权为0就放在前面,这样就保证了两段性,单调性。
这样就能O(n)求解。
1 #include <cstdio> 2 #include <cstring> 3 #include <queue> 4 5 const int N = 510; 6 7 int G[N][N]; 8 bool vis[N][N]; 9 10 struct Sta { 11 int x, y, dis; 12 Sta(int x = 0, int y = 0, int dis = 0) { 13 this->x = x; 14 this->y = y; 15 this->dis = dis; 16 } 17 }; 18 19 void BFS(int x, int y) { 20 vis[1][1] = 1; 21 std::deque<Sta> Q; 22 Q.push_back(Sta(1, 1, 0)); 23 bool f = 0; 24 while(!Q.empty()) { 25 Sta st = Q.front(); 26 Q.pop_front(); 27 int i = st.x; 28 int j = st.y; 29 vis[i][j] = 1; 30 if(i == x && j == y) { 31 f = 1; 32 printf("%d\n", st.dis); 33 break; 34 } 35 36 if(!vis[i + 1][j + 1]) { 37 if(!G[i][j]) { 38 Q.push_front(Sta(i + 1, j + 1, st.dis)); 39 } 40 else { 41 Q.push_back(Sta(i + 1, j + 1, st.dis + 1)); 42 } 43 } 44 45 if(!vis[i - 1][j - 1]) { 46 if(!G[i - 1][j - 1]) { 47 Q.push_front(Sta(i - 1, j - 1, st.dis)); 48 } 49 else { 50 Q.push_back(Sta(i - 1, j - 1, st.dis + 1)); 51 } 52 } 53 54 if(!vis[i + 1][j - 1]) { // ↙ 55 if(G[i][j - 1]) { 56 Q.push_front(Sta(i + 1, j - 1, st.dis)); 57 } 58 else { 59 Q.push_back(Sta(i + 1, j - 1, st.dis + 1)); 60 } 61 } 62 63 if(!vis[i - 1][j + 1]) { // ↗ 64 if(G[i - 1][j]) { 65 Q.push_front(Sta(i - 1, j + 1, st.dis)); 66 } 67 else { 68 Q.push_back(Sta(i - 1, j + 1, st.dis + 1)); 69 } 70 } 71 72 } 73 if(!f) { 74 printf("NO SOLUTION\n"); 75 } 76 77 return; 78 } 79 80 inline void clear() { 81 memset(vis, 0, sizeof(vis)); 82 memset(G, 0, sizeof(G)); 83 return; 84 } 85 86 inline void pre(int n, int m) { 87 for(int i = 1; i <= n + 1; i++) { 88 vis[i][0] = vis[i][m + 2] = 1; 89 } 90 for(int j = 0; j <= m + 2; j++) { 91 vis[0][j] = vis[n + 2][j] = 1; 92 } 93 return; 94 } 95 96 int main() { 97 int T, m, n; 98 scanf("%d", &T); 99 while(T--) { 100 clear(); 101 scanf("%d%d", &n, &m); 102 pre(n, m); 103 for(int i = 1; i <= n; i++) { 104 for(int j = 1; j <= m; j++) { 105 106 char c = getchar(); 107 while(c != '\\' && c != '/') { 108 c = getchar(); 109 } 110 G[i][j] = (c == '/'); 111 } 112 } 113 BFS(n + 1, m + 1); 114 } 115 116 return 0; 117 }