Uva1601双向BFS

来源:互联网 发布:天刀捏脸数据女赵丽颖 编辑:程序博客网 时间:2024/05/22 05:07
//双向BFS#include<cstdio>#include<cstring>#include<cctype>#include<queue>#include <iostream>using namespace std;const int N    = 20;const int maxn = 200;const int dx[] = {1,0,-1,0,0};const int dy[] = {0,-1,0,1,0};int n,m,k;char maze[N][N];int x[maxn],y[maxn],cnt,G[maxn][5],deg[maxn],id[maxn][maxn];int s[3],t[3];int d[maxn][maxn][maxn],bd[maxn][maxn][maxn];int ID(int a,int b,int c){    return (a<<16)|(b<<8)|c;//将状态压缩成一个整数,方便储存}void Memset(){    memset(d,-1,sizeof(d));    memset(bd,-1,sizeof(bd));}bool conflict(int a, int b, int a2, int b2) {  return a2 == b2 || (a2 == b && b2 == a);//判断是否冲突}queue<int> q;bool bfs()//正向BFS{    int value;    int uu=q.front();    int aa=(uu>>16)&0xff,bb=(uu>>8)&0xff,cc=uu&0xff;    value=d[aa][bb][cc];    while(!q.empty())    {        int u=q.front();        int a=(u>>16)&0xff,b=(u>>8)&0xff,c=u&0xff;        if(d[a][b][c]!=value) return false;        if(bd[a][b][c]!=-1) return true;        for(int i=0; i<deg[a]; i++)        {            int na=G[a][i];            for(int j=0; j<deg[b]; j++)            {                int nb=G[b][j];                for(int k=0; k<deg[c]; k++)                {                    int nc=G[c][k];                    if(conflict(a,b,na,nb)) continue;                    if(conflict(a,c,na,nc)) continue;                    if(conflict(b,c,nb,nc)) continue;                    if(d[na][nb][nc]==-1)                    {                        d[na][nb][nc]=d[a][b][c]+1;                        q.push(ID(na,nb,nc));                    }                }            }        }        q.pop();    }    return false;}queue<int> p;int back_bfs(){//反向BFS    int value;    int uu=p.front();    int aa=(uu>>16)&0xff,bb=(uu>>8)&0xff,cc=uu&0xff;    value=bd[aa][bb][cc];    while(!p.empty())    {        int u=p.front();        int a=(u>>16)&0xff,b=(u>>8)&0xff,c=u&0xff;        if(bd[a][b][c]!=value) return false;        if(d[a][b][c]!=-1) return true;        for(int i=0; i<deg[a]; i++)        {            int na=G[a][i];            for(int j=0; j<deg[b]; j++)            {                int nb=G[b][j];                for(int k=0; k<deg[c]; k++)                {                    int nc=G[c][k];                    if(conflict(a,b,na,nb)) continue;                    if(conflict(a,c,na,nc)) continue;                    if(conflict(b,c,nb,nc)) continue;                    if(bd[na][nb][nc]==-1)                    {                        bd[na][nb][nc]=bd[a][b][c]+1;                        p.push(ID(na,nb,nc));                    }                }            }        }        p.pop();    }    return false;}int BFS(){while(!q.empty()) q.pop();while(!p.empty()) p.pop();q.push(ID(s[0],s[1],s[2]));p.push(ID(t[0],t[1],t[2]));Memset();d[s[0]][s[1]][s[2]]=0; bd[t[0]][t[1]][t[2]]=0;int step=0,ok=0;while(!p.empty()&&!q.empty()){//正向BFS与反向BFS交替进行,同时统计步数        if(bfs()){            ok=1;            break;        }        else step++;        if(back_bfs()){            ok=1;            break;        }        else step++;}return ok ? step:-1;}int main(){    int w,h,n;    while(scanf("%d%d%d\n",&w,&h,&n)==3&&n!=0){        char maze[20][20];        for(int i=0;i<h;i++){            fgets(maze[i],20,stdin);        }        int cnt=0,x[256],y[256],id[20][20];        //将空地编上ID号        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 j=0;j<5;j++){                int nx = x[i]+dx[j], ny = y[i]+dy[j];                if(maze[nx][ny]!='#'){                    G[i][deg[i]++]=id[nx][ny];                }            }        }        //不足三个鬼时添加鬼,方便统一处理        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;}

1 0
原创粉丝点击