题意是给你一个迷宫,有两个出口,找出最长的从迷宫内任意一点到出口的最短距离。

一开始想到的是dijkstra,在两个出口分别运行一次,取每个点到两个出口距离中最短的,再去其中最大的即可。

然后想到其实分别从两个出口作BFS,标注每个点的距离即可。

View Code
  1 /*
  2 ID: xjtuacm1
  3 PROG: maze1
  4 LANG: C++
  5 */
  6 #include<iostream>
  7 #include<stack>
  8 #include<cstring>
  9 #include<cstdio>
 10 #include<queue>
 11 #include<algorithm>
 12 #include<set>
 13 #include<map>
 14 using namespace std;
 15 const int W = 38;
 16 const int H = 100;
 17 const int INF = 0x3f3f3f3f;
 18 
 19 const int dir[4] = { 1, 2, 4, 8};
 20 
 21 int stage[H][W];
 22 int color[H][W];
 23 int h, w;
 24 
 25 struct Point
 26 {
 27     int x, y;
 28     Point(int xx = 0, int yy = 0) :x(xx), y(yy) {}
 29     bool operator<(const Point& rhs) const
 30     {
 31         if(x == rhs.x)
 32             return y < rhs.y;
 33         return x < rhs.x;
 34     }
 35 
 36     bool connect(int d) const
 37     {
 38         return !(stage[x][y] & dir[d]);
 39     }
 40 
 41     Point next(int d) const
 42     {
 43         switch(dir[d])
 44         {
 45         case 1:
 46             return Point(x, y-1);
 47         case 2:
 48             return Point(x-1, y);
 49         case 4:
 50             return Point(x, y+1);
 51         case 8:
 52             return Point(x+1, y);
 53         }
 54         return Point();
 55     }
 56 };
 57 
 58 void init()
 59 {
 60     for(int i = 0; i!= h; i++)
 61         for(int j = 0; j!= w; j++)
 62         {
 63             stage[i][j] = 0xF;
 64             color[i][j] = INF;
 65         }
 66 }
 67 
 68 void addEdge(const Point& u, const Point& v)
 69 {
 70     const Point& a = u<v ? u : v;
 71     const Point& b = u<v ? v : u;
 72     if(a.x == b.x)
 73     {
 74         stage[a.x][a.y] ^= 1<<2;
 75         stage[b.x][b.y] ^= 1;
 76     }
 77     if(a.y == b.y)
 78     {
 79         stage[a.x][a.y] ^= 1<<3;
 80         stage[b.x][b.y] ^= 1<<1;
 81     }
 82 }
 83 
 84 void bfs(const Point& src)
 85 {
 86     color[src.x][src.y] = 1;
 87     queue<pair<Point, int> > que;
 88     que.push(make_pair(src, 1));
 89 
 90     while(!que.empty())
 91     {
 92         Point pt = que.front().first;
 93         int dis = que.front().second;
 94         que.pop();
 95 
 96         for(int i = 0; i!= 4; i++)
 97         {
 98             if(pt.connect(i))
 99             {
100                 Point nxt = pt.next(i);
101                 if(dis+1 < color[nxt.x][nxt.y])
102                 {
103                     color[nxt.x][nxt.y] = dis + 1;
104                     que.push(make_pair(nxt, color[nxt.x][nxt.y]));
105                 }
106             }
107         }
108     }
109 }
110 
111 int main(int argc, char *argv[])
112 {
113     freopen("maze1.in", "r", stdin);
114 #ifndef USACO
115     freopen("maze1.out", "w", stdout);
116 #endif // USACO
117 
118 
119     scanf("%d %d", &w, &h); getchar();
120     init();
121 
122     Point extCell[2];
123     int extCnt = 0;
124 
125     char line[2*W + 2];
126 
127     // first line
128     gets(line);
129     for(int i = 0; i!= strlen(line); i++)
130     {
131         if(line[i] == ' ')
132             extCell[extCnt++] = Point(0, (i - 1) / 2);
133     }
134     for(int i = 0; i!= 2 * h - 1; i++)
135     {
136         gets(line);
137         if(i & 1)
138         {
139             for(int j = 0; j != strlen(line); j++)
140             {
141                 if(line[j] == ' ')
142                 {
143                     addEdge(Point((i-1)/2, (j-1)/2),
144                             Point((i+1)/2, (j-1)/2) );
145                 }
146             }
147         }
148         else
149         {
150             if(line[0] == ' ')
151             {
152                 extCell[extCnt++] = Point(i / 2, 0);
153             }
154             if(line[strlen(line) - 1] == ' ')
155             {
156                 extCell[extCnt++] = Point(i / 2, w - 1);
157             }
158             for(int j = 2; j< strlen(line) - 1; j+= 2)
159             {
160                 if(line[j] == ' ')
161                 {
162                     addEdge(Point(i/2, j/2 - 1),
163                             Point(i/2, j/2) );
164                 }
165             }
166         }
167     }
168     // last line
169     gets(line);
170     for(int i = 0; i!= strlen(line); i++)
171     {
172         if(line[i] == ' ')
173             extCell[extCnt++] = Point(h-1, (i - 1) / 2);
174     }
175 
176     bfs(extCell[0]);
177     bfs(extCell[1]);
178 
179     int m = 0;
180     for(int i = 0; i!= h; i++)
181         for(int j = 0; j!= w; j++)
182         m = max(m, color[i][j]);
183 
184     printf("%d\n", m);
185 
186 
187     return 0;
188 }