电路维修

这题。。。转成图论来做。

是这样的:对于每个方格,连接它已经连通的两个点,边权为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 }
AC代码

 

posted @ 2018-06-20 20:21  garage  阅读(140)  评论(0编辑  收藏  举报