zoukankan      html  css  js  c++  java
  • UVA 1601 双向BFS

     

    但是我们还不是很清楚每一次的状态怎么储存?我们可以用一个结构体,将每次的位置存起来,但是这个程序中用了一个更好的储存方法:我们知道最大的格数是16*16个,也就是256个,那么我们转换为二进制表示就是8位数,那么我们可以使用24位的二进制表示啊!然后我们再进行解压缩,所以这就是很神奇的地方!

    普通BFS 

    #include<iostream>
    #include<string>
    #include<cmath>
    #include<cstring>
    #include<vector>
    #include<map>
    #include<set>
    #include<algorithm>
    #include<queue>
    #include<stack>
    #include<sstream>
    #include<cstdio>
    #define INF 0x3f3f3f3f
    //const int maxn = 1e6 + 5;
    const double PI = acos(-1.0);
    typedef long long ll;
    using namespace std;
    
    const int maxn = 150;
    const int maxs = 20;
    const int dx[] = { 1,-1,0,0,0 };
    const int dy[] = { 0,0,1,-1,0 };
    
    inline int ID(int a, int b, int c) {
        return (a << 16) | (b << 8) | c;
    }
    
    int s[3], t[3];
    
    int deg[maxn];    //记录每个编号为i的空格周围可以走的步数
    int G[maxn][5];   
    
    inline bool conflict(int a, int b, int a2, int b2) {
        return    a2 == b2 || (a2 == b && b2 == a);
    }
    
    int d[maxn][maxn][maxn];
    
    int bfs() {
        queue<int> q;
        memset(d, -1, sizeof d);
        q.push(ID(s[0], s[1], s[2]));
        d[s[0]][s[1]][s[2]] = 0;
        while (!q.empty()) {
            int u = q.front();
            q.pop();
            int a = (u >> 16) & 0xff, b = (u >> 8) & 0xff, c = u & 0xff;   //解码出三个鬼的位置
            if (a == t[0] && b == t[1] && c == t[2]) return d[a][b][c];
            for (int i = 0; i < deg[a]; i++) {
                int a2 = G[a][i];
                for (int j = 0; j < deg[b]; j++) {
                    int b2 = G[b][j];
                    if (conflict(a, b, a2, b2)) continue;
                    for (int k = 0; k < deg[c]; k++) {
                        int c2 = G[c][k];
                        if (conflict(a, c, a2, c2)) continue;
                        if (conflict(b, c, b2, c2)) continue;
                        if (d[a2][b2][c2] != -1) continue;
                        d[a2][b2][c2] = d[a][b][c] + 1;
                        q.push(ID(a2, b2, c2));
                    }
                }
            }
        }
        return -1;
    }
    
    int main() {
        int w, h, n;
    
        while (scanf("%d%d%d", &w, &h, &n) == 3 && n) {
            char maze[20][20];
            for (int i = 0; i < h; i++) fgets(maze[i], 20, stdin);
    
            int cnt, x[maxn], y[maxn], id[maxs][maxs];
            cnt = 0;
            for (int i = 0; i < h; i++) {
                for(int j=0;j<w;j++)
                    if (maze[i][j] != '#') {
                        x[cnt] = i;
                        y[cnt] = j;
                        id[i][j] = cnt;
                        if (islower(maze[i][j])) s[maze[i][j] - 'a'] = cnt;
                        else if (isupper(maze[i][j])) t[maze[i][j] - 'A'] = cnt;
                        cnt++;
                    }
            }
    
            for (int i = 0; i < cnt; i++) {
                deg[i] = 0;
                for (int dir = 0; dir < 5; dir++) {
                    int xx = x[i] + dx[dir], yy = y[i] + dy[dir];
                    if (maze[xx][yy] != '#') G[i][deg[i]++] = id[xx][yy];
                }
            }
    
            if (n <= 2) {
                deg[cnt] = 1;
                G[cnt][0] = cnt;
                s[2] = t[2] = cnt++;
            }
            if (n <= 1) {
                deg[cnt] = 1;
                G[cnt][0] = cnt;
                s[1] = t[1] = cnt++;
            }
    
            printf("%d\n", bfs());
    
        }
        return 0;
    }
    View Code

    双向BFS

    #include<iostream>
    #include<string>
    #include<cmath>
    #include<cstring>
    #include<vector>
    #include<map>
    #include<set>
    #include<algorithm>
    #include<queue>
    #include<stack>
    #include<sstream>
    #include<cstdio>
    #define INF 0x3f3f3f3f
    //const int maxn = 1e6 + 5;
    const double PI = acos(-1.0);
    typedef long long ll;
    using namespace std;
    
    const int maxn = 150;
    const int maxs = 20;
    const int dx[] = { 1,-1,0,0,0 };
    const int dy[] = { 0,0,1,-1,0 };
    
    inline int ID(int a, int b, int c) {
        return (a << 16) | (b << 8) | c;
    }
    
    int s[3], t[3];
    
    int deg[maxn];    //记录每个编号为i的空格周围可以走的步数
    int G[maxn][5];   
    char maze[maxn][maxn];
    int color[maxn][maxn][maxn];
    
    inline bool conflict(int a, int b, int a2, int b2) {
        //两个鬼是exchange位置(违反第2条)
        //两个鬼移动到同一个格子(违反第1条)
        return    a2 == b2 || (a2 == b && b2 == a);
    }
    
    int d1[maxn][maxn][maxn];
    
    int bfs() {
        queue<int> qf;
        queue<int> qb;
    
        d1[s[0]][s[1]][s[2]] = 0;
        d1[t[0]][t[1]][t[2]] = 1;
    
        qf.push(ID(s[0], s[1], s[2]));
        qb.push(ID(t[0], t[1], t[2]));
    
        while (!qf.empty() || !qb.empty()) {
            int fnum = qf.size(), bnum = qb.size();
            while (fnum--) {
                int u = qf.front(); qf.pop();
                int a = (u >> 16) & 0xff, b = (u >> 8) & 0xff, c = u & 0xff;
    
                for (int i = 0; i < deg[a]; i++) {
                    int a2 = G[a][i];
                    for (int j = 0; j < deg[b]; j++) {
                        int b2 = G[b][j];
                        if (conflict(a, b, a2, b2)) continue;
                        for (int k = 0; k < deg[c]; k++) {
                            int c2 = G[c][k];
                            if (conflict(a, c, a2, c2) || conflict(b, c, b2, c2)) continue;
                            if (color[a2][b2][c2] == 0) {
                                d1[a2][b2][c2] = d1[a][b][c] + 1;
                                color[a2][b2][c2] = 1;
                                qf.push(ID(a2, b2, c2));
                            }
                            else if (color[a2][b2][c2] == 2) {
                                return d1[a][b][c] + d1[a2][b2][c2];
                            }
                        }
                    }
                }
            }
            while (bnum--) {
                int u = qb.front(); qb.pop();
                int a = (u >> 16) & 0xff, b = (u >> 8) & 0xff, c = u & 0xff;
    
                for (int i = 0; i < deg[a]; i++) {
                    int a2 = G[a][i];
                    for (int j = 0; j < deg[b]; j++) {
                        int b2 = G[b][j];
                        if (conflict(a, b, a2, b2)) continue;
                        for (int k = 0; k < deg[c]; k++) {
                            int c2 = G[c][k];
                            if (conflict(a, c, a2, c2) || conflict(b, c, b2, c2)) continue;
                            if (color[a2][b2][c2] == 0) {
                                d1[a2][b2][c2] = d1[a][b][c] + 1;
                                color[a2][b2][c2] = 2;
                                qb.push(ID(a2, b2, c2));
                            }
                            else if (color[a2][b2][c2] == 1) {
                                return d1[a][b][c] + d1[a2][b2][c2];
                            }
                        }
                    }
                }
            }
        }
        return -1;
    }
    
    int main() {
        int w, h, n;
        while (scanf("%d%d%d", &w, &h, &n) == 3, n) {
            for (int i = 0; i < h; i++) fgets(maze[i], 20, stdin);
            int cnt = 0;
            int x[maxn], y[maxn];
            int id[maxs][maxs];
            for (int i = 0; i < h; i++) {
                for (int j = 0; j < w; j++) {
                    if (maze[i][j] != '#') {
                        x[cnt] = i, y[cnt] = j, id[i][j] = cnt;
                        if (islower(maze[i][j])) s[maze[i][j] - 'a'] = cnt;
                        else if (isupper(maze[i][j])) t[maze[i][j] - 'A'] = cnt;
                        cnt++;
                    }
                }
            }
    
            for (int i = 0; i < cnt; i++) {
                for (int j = 0; j < 5; j++) {
                    int xx = x[i] + dx[j], yy = y[i] + dy[j];
                    if (maze[xx][yy] != '#') G[i][deg[i]++] = id[xx][yy];
                }
            }
    
            if (n <= 2) {
                deg[cnt] = 1;
                G[cnt][0] = cnt;
                s[2] = t[2] = cnt++;
            }
            if (n <= 1) {
                deg[cnt] = 1;
                G[cnt][0] = cnt;
                s[1] = t[1] = cnt++;
            }
    
            memset(d1, 0, sizeof d1);
            memset(color, 0, sizeof color);
    
            if (s[0] == t[0] && s[1] == t[1] && s[2] == t[2]) printf("0\n");
            else printf("%d\n", bfs());
        }
        return 0;
    }
    View Code
  • 相关阅读:
    《我们不一样》β冲刺_1
    《我们不一样》Alpha冲刺_1-5
    《我们不一样》团队项目软件设计方案
    如何绘制符合规范的流程图?
    《我们不一样》团队项目软件系统设计改进
    <Dare To Dream>团队项目用户验收评审
    Beta冲刺 第四天
    Beta冲刺 第三天
    Beta冲刺 第二天
    Beta冲刺 第一天
  • 原文地址:https://www.cnblogs.com/hznumqf/p/12358464.html
Copyright © 2011-2022 走看看