题目链接:时空门问题

简单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

*/

  

 

posted on 2016-04-09 10:36  小小八  阅读(187)  评论(0编辑  收藏  举报