UVA - 10047 The Monocycle

从刘汝佳训练指南上看到的一道题,看了解释之后发现是一道最短路问题,(x,y,d,c)表示位于(x,y)点面向为d,颜色为c的状态,然后每个状态有左转,右转,前进3个转移方式也就对应三条边,然后建图求最短路就可以了。

代码:

  1 #include <iostream>
  2 #include <sstream>
  3 #include <cstdio>
  4 #include <climits>
  5 #include <cstring>
  6 #include <cstdlib>
  7 #include <string>
  8 #include <map>
  9 #include <cmath>
 10 #include <vector>
 11 #include <queue>
 12 #include <algorithm>
 13 #define esp 1e-6
 14 #define pb push_back
 15 #define in  freopen("in.txt", "r", stdin);
 16 #define out freopen("out.txt", "w", stdout);
 17 #define print(a) printf("%d\n",(a));
 18 #define bug puts("********))))))");
 19 #define stop  system("pause");
 20 #define Rep(i, c) for(__typeof(c.end()) i = c.begin(); i != c.end(); i++)
 21 #define inf 0x0f0f0f0f
 22 using namespace std;
 23 typedef long long  LL;
 24 typedef vector<int> VI;
 25 typedef pair<int, int> pii;
 26 typedef vector<pii,int> VII;
 27 typedef vector<int>:: iterator IT;
 28 const int maxn = 100000;
 29 const int maxm = 60*25*25+100;
 30 struct EDGE
 31 {
 32     int i, c;
 33     EDGE *next, *ani;
 34 } *Edge[maxn], E[maxm];
 35 int cnt = 0;
 36 int src;
 37 int R, C;
 38 int node[30][30][10][10];
 39 int dx[] = {-1, 0, 1, 0};
 40 int dy[] = {0, 1, 0, -1};
 41 int dis[maxn], inq[maxn];
 42 char maze[30][30];
 43 void add(int i, int j, int c, EDGE &e1)
 44 {
 45     e1.i = j, e1.next = Edge[i], e1.c = c, Edge[i] = &e1;
 46     cnt++;
 47 }
 48 void init(void)
 49 {
 50     cnt = 0;
 51     memset(Edge, 0, sizeof(Edge));
 52 }
 53 void spfa(int ss)
 54 {
 55     memset(inq, 0, sizeof(inq));
 56     memset(dis, 0x0f, sizeof(dis));
 57     dis[ss] = 0;
 58     queue<int> q;
 59     inq[ss] = 1;
 60     q.push(ss);
 61     while(!q.empty())
 62     {
 63         int u = q.front(), v;
 64         q.pop();
 65         inq[u] = 0;
 66         for(EDGE *p = Edge[u]; p; p = p->next)
 67         {
 68 //            print(p->i)
 69             if(dis[v = p->i] > dis[u] + p->c)
 70                 if(dis[v] = dis[u] + p->c, !inq[v])
 71                     inq[v] = 1, q.push(v);
 72         }
 73     }
 74 }
 75 void build_graph()
 76 {
 77     for(int i = 0; i < R; i++)
 78         for(int j = 0; j < C; j++)
 79             if(maze[i][j] == '.')
 80                 for(int k = 0; k < 4; k++)
 81                     for(int l = 0; l < 5; l++)
 82                     {
 83                         int u = node[i][j][k][l], v;
 84                         v = node[i][j][(k - 1 + 4)%4][l];
 85                         add(u, v, 1, E[cnt]);
 86                         v = node[i][j][(k + 1)%4][l];
 87                         add(u, v, 1, E[cnt]);
 88                         int ii = i + dx[k];
 89                         int jj = j + dy[k];
 90                         if(ii >= 0 && ii < R && jj >= 0 && jj < C && maze[ii][jj] == '.')
 91                         {
 92                             v = node[ii][jj][k][(l+1)%5];
 93                             add(u, v, 1, E[cnt]);
 94                         }
 95                     }
 96 }
 97 int main(void)
 98 {
 99     int t = 1;
100     for(int i = 0; i < 30; i++)
101         for(int j = 0; j < 30; j++)
102             for(int k = 0; k < 10; k++)
103                 for(int l = 0; l < 10; l++)
104                     node[i][j][k][l] = i*(30*10*10)+j*(10*10)+k*10+l;
105     while(scanf("%d%d", &R, &C), R||C)
106     {
107         init();
108         int sx, sy, tx, ty;
109         for(int i = 0; i < R; i++)
110         {
111             scanf("%s", maze[i]);
112             for(int j = 0; j < C; j++)
113                 if(maze[i][j] == 'S')
114                 {
115                     sx = i;
116                     sy = j;
117                     maze[i][j] = '.';
118                 }
119                 else if(maze[i][j] == 'T')
120                 {
121                     tx = i;
122                     ty = j;
123                     maze[i][j] = '.';
124                 }
125         }
126         build_graph();
127         src = node[sx][sy][0][0];
128         spfa(src);
129         int ans = inf;
130         for(int k = 0; k < 4; k++)
131         {
132             int end = node[tx][ty][k][0];
133             ans = min(ans, dis[end]);
134         }
135         if(t - 1)
136             puts("");
137         printf("Case #%d\n", t);
138         t++;
139         if(ans == inf)
140             puts("destination not reachable");
141         else printf("minimum time = %d sec\n", ans);
142     }
143     return 0;
144 }
View Code

 

下面是汝佳神牛的代码,不禁感叹真是一目了然啊。、

 1 #include <iostream>
 2 #include <sstream>
 3 #include <cstdio>
 4 #include <climits>
 5 #include <cstring>
 6 #include <cstdlib>
 7 #include <string>
 8 #include <map>
 9 #include <cmath>
10 #include <vector>
11 #include <queue>
12 #include <algorithm>
13 #define esp 1e-6
14 #define pb push_back
15 #define in  freopen("in.txt", "r", stdin);
16 #define out freopen("out.txt", "w", stdout);
17 #define print(a) printf("%d\n",(a));
18 #define bug puts("********))))))");
19 #define stop  system("pause");
20 #define Rep(i, c) for(__typeof(c.end()) i = c.begin(); i != c.end(); i++)
21 #define inf 0x0f0f0f0f
22 using namespace std;
23 typedef long long  LL;
24 typedef vector<int> VI;
25 typedef pair<int, int> pii;
26 typedef vector<pii,int> VII;
27 typedef vector<int>:: iterator IT;
28 const int maxr = 25 + 5;
29 const int maxc = 25 + 5;
30 struct State
31 {
32     int r, c, dir, color;
33     State(int r, int c, int dir, int color): r(r), c(c), dir(dir), color(color) {}
34 };
35 int R, C, ans;
36 int d[maxr][maxc][4][5], vis[maxr][maxc][4][5];
37 char maze[maxr][maxc];
38 int sr, sc, tr, tc;
39 int dr[] = {-1, 0, 1, 0};
40 int dc[] = {0, 1, 0, -1};
41 queue<State> q;
42 void update(int r, int c, int dir, int color, int v)
43 {
44     if(r <0 || r >= R || c < 0 || c >= C || maze[r][c] != '.' || vis[r][c][dir][color]) return;
45     vis[r][c][dir][color] = 1;
46     d[r][c][dir][color] = v;
47     q.push(State(r, c, dir, color));
48     if(r == tr && c == tc && color == 0)
49         ans = min(ans, v);
50 }
51 void bfs(State st)
52 {
53     vis[st.r][st.c][st.dir][st.color] = 1;
54     d[st.r][st.c][st.dir][st.color] = 0;
55     q.push(st);
56     while(!q.empty())
57     {
58         State st = q.front();
59         q.pop();
60         int v = d[st.r][st.c][st.dir][st.color] + 1;
61         update(st.r, st.c, (st.dir+3)%4, st.color, v);
62         update(st.r+dr[st.dir], st.c+dc[st.dir], st.dir, (st.color+1)%5, v);
63         update(st.r, st.c, (st.dir+1)%4, st.color, v);
64     }
65 }
66 int main(void)
67 {
68     
69     int t = 1;
70     while(scanf("%d%d", &R, &C), C||R)
71     {
72         if(t - 1)
73             puts("");
74         memset(vis, 0, sizeof(vis));
75         for(int i = 0; i < R; i++)
76         {
77             scanf("%s", maze[i]);
78             for(int j = 0; j < C; j++)
79                 if(maze[i][j] == 'S')
80                     sr = i, sc = j;
81                 else if(maze[i][j] == 'T')
82                     tr = i, tc = j;
83         }
84         ans = inf;
85         maze[sr][sc] = maze[tr][tc] = '.';
86         bfs(State(sr, sc, 0, 0));
87         printf("Case #%d\n", t);
88         if(ans != inf)
89             printf("minimum time = %d sec\n", ans);
90         else puts("destination not reachable");
91         t++;
92     }
93     return 0;
94 }
View Code

 

posted on 2013-09-19 11:01  rootial  阅读(209)  评论(0编辑  收藏  举报

导航