题目链接:时空门问题
简单bfs,每个格子移动的方式除了上下左右,还有时空门,开始想着用邻接表保存每个点能通过时空门到达的点就ok了。很快的敲出来,很快的WA了。长久的dbug并没有发现error。然后换成vector存储,AC,再换成邻接表WA......感觉明明一模一样的好吗...讨厌bug!【怒】
=============================第二天晚上,神奇的大腿发现,我的head数组开成了maxn,然而实际上是maxn*maxn...沃日...最多有maxn*maxn个点啊....................早知道重构好了....
邻接表代码:AC
#include <stdio.h> #include <string.h> #include <iostream> #define maxn 600 using namespace std; char mp[maxn][maxn]; int n, m; struct Node { int u, v, nxt; }edge[maxn*maxn]; struct Point { int x, y; int step; }point[maxn*maxn], st, ed, temp; int head[maxn*maxn]; int tot; void addEdge(int u, int v) { edge[tot].u = u; edge[tot].v = v; edge[tot].nxt = head[u]; head[u] = tot++; } Point que[maxn*maxn]; int top, tail; bool vis[maxn][maxn]; int dir[4][2] = {1, 0, -1, 0, 0, 1, 0, -1}; bool check(Point a) { if (a.x >= 0 && a.x < n && a.y >= 0 && a.y < m && mp[a.x][a.y] != '#' && !vis[a.x][a.y]) return true; return false; } void bfs(Point st) { top = 0, tail = -1; vis[st.x][st.y] = 1; que[++tail] = st; while(top <= tail) { Point now = que[top++]; if (now.x == ed.x && now.y == ed.y) { ed.step = now.step; return; } for (int i=0; i<4; ++i) { Point nxt; nxt.x = now.x + dir[i][0]; nxt.y = now.y + dir[i][1]; if (check(nxt)) { vis[nxt.x][nxt.y] = 1; nxt.step = now.step + 1; que[++tail] = nxt; } } int stp = now.x * m + now.y; for (int i=head[stp]; i!=-1; i=edge[i].nxt) { int edp = edge[i].v; Point nxt; nxt.x = edp / m, nxt.y = edp % m; if (check(nxt)) { vis[nxt.x][nxt.y] = 1; nxt.step = now.step + 1; que[++tail] = nxt; } } } return; } int main() { while(~scanf("%d%d", &n, &m)) { tot = 0; memset(head, -1, sizeof(head)); memset(vis, 0, sizeof(vis)); getchar(); for (int i=0; i<n; ++i) { for (int j=0; j<m; ++j) { scanf("%c", &mp[i][j]); if (mp[i][j] == 's') { st.x = i, st.y = j; st.step = 0; } else if (mp[i][j] == 't') { ed.x = i, ed.y = j; } } if (i != n-1) scanf(" "); } for (int i=0; i<n*m; ++i) { int t; scanf("%d", &t); for (int j=0; j<t; ++j) { int edx, edy; scanf("%d%d", &edx, &edy); edx -= 1, edy -= 1; addEdge(i, edx*m+edy); } } // for (int i=0; i<n*m; ++i) { // cout << head[i] << ".... "; // for (int j=head[i]; j!=-1; j=edge[j].nxt) { // cout << edge[j].u << " " << edge[j].v << endl; // } // cout << "++++++++++++++ "; // } bfs(st); printf("%d ", ed.step); } return 0; } /* 2 3 s.# ..t 1 2 2 0 0 0 1 1 2 0 */
vector代码:AC
#include <stdio.h> #include <string.h> #include <iostream> #define maxn 600 #include <vector> using namespace std; char mp[maxn][maxn]; int n, m; vector<int>num[maxn*maxn]; struct Point { int x, y; int step; }point[maxn*maxn], st, ed, temp; int tot; Point que[maxn*maxn]; int top, tail; bool vis[maxn][maxn]; int dir[4][2] = {1, 0, -1, 0, 0, 1, 0, -1}; bool check(Point a) { if (a.x >= 0 && a.x < n && a.y >= 0 && a.y < m && mp[a.x][a.y] != '#' && !vis[a.x][a.y]) return true; return false; } void bfs(Point st) { top = 0, tail = -1; vis[st.x][st.y] = 1; que[++tail] = st; while(top <= tail) { Point now = que[top++]; if (now.x == ed.x && now.y == ed.y) { ed.step = now.step; return; } for (int i=0; i<4; ++i) { Point nxt; nxt.x = now.x + dir[i][0]; nxt.y = now.y + dir[i][1]; if (check(nxt)) { vis[nxt.x][nxt.y] = 1; nxt.step = now.step + 1; que[++tail] = nxt; } } int stp = now.x * m + now.y; for (int i=0; i<num[stp].size(); ++i) { int edp = num[stp][i]; Point nxt; nxt.x = edp / m, nxt.y = edp % m; if (check(nxt)) { vis[nxt.x][nxt.y] = 1; nxt.step = now.step + 1; que[++tail] = nxt; } } } return; } int main() { while(~scanf("%d%d", &n, &m)) { tot = 0; memset(vis, 0, sizeof(vis)); getchar(); for (int i=0; i<n; ++i) { for (int j=0; j<m; ++j) { scanf("%c", &mp[i][j]); if (mp[i][j] == 's') { st.x = i, st.y = j; st.step = 0; } else if (mp[i][j] == 't') { ed.x = i, ed.y = j; } num[i*m+j].clear(); } if (i != n-1) scanf(" "); } for (int i=0; i<n*m; ++i) { int t; scanf("%d", &t); for (int j=0; j<t; ++j) { int edx, edy; scanf("%d%d", &edx, &edy); edx -= 1, edy -= 1; num[i].push_back(edx*m+edy); } } bfs(st); printf("%d ", ed.step); } return 0; } /* 2 3 s.# ..t 1 2 2 0 0 0 1 1 2 0 */