题目链接:时空门问题
简单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("\n");
} 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] << "....\n";
// for (int j=head[i]; j!=-1; j=edge[j].nxt) {
// cout << edge[j].u << " " << edge[j].v << endl;
// }
// cout << "++++++++++++++\n";
// } bfs(st);
printf("%d\n", 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("\n");
} 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\n", ed.step);
}
return 0;
} /*
2 3
s.#
..t
1
2 2
0
0
0
1
1 2
0 */