UVa1601 The Morning after Halloween(双向bfs)

Posted noble_

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了UVa1601 The Morning after Halloween(双向bfs)相关的知识,希望对你有一定的参考价值。

题目

题目
?


?

分析

双向bfs,对着书打的,我还调了好久。
?


?

代码

#include<cstdio>
#include<cstring>
#include<cctype>
#include<queue>
using namespace std;

const int maxs=20,maxn=150;
const int dx[]={1,-1,0,0,0},dy[]={0,0,1,-1,0};
int s[3],t[3];
int deg[maxn],G[maxn][5];  
int dis[maxn][maxn][maxn],dis_back[maxn][maxn][maxn];  
int id[maxn][maxn];

inline int ID(int a,int b,int c)
{
    return (a<<16)|(b<<8)|c;
}

inline bool conflict(int a,int b,int a2,int b2)
{
    return a2==b2 || (a2==b && b2==a); 
}

int bfs(queue<int>& q,int d[maxn][maxn][maxn])
{
    int u=q.front(); q.pop();
    int a = (u>>16)&0xff, b = (u>>8)&0xff, c = u&0xff;
    if(dis[a][b][c]!=-1 && dis_back[a][b][c]!=-1) return dis[a][b][c]+dis_back[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 solve()
{
    queue<int> q;
    q.push(ID(s[0],s[1],s[2]));
    memset(dis,-1,sizeof(dis));
    dis[s[0]][s[1]][s[2]]=0;
    
    queue<int> q_back;
    q_back.push(ID(t[0],t[1],t[2]));
    memset(dis_back,-1,sizeof(dis_back));
    dis_back[t[0]][t[1]][t[2]]=0;
    
    int ans,t=0;
    while(1)
    {
        t++;
        ans=bfs(q,dis);
        if(ans!=-1) return ans;
        ans=bfs(q_back,dis_back);
        if(ans!=-1) return ans;
    }
    
    return -1;
}
int main()
{
    int w,h,n;
    while(scanf("%d%d%d",&w,&h,&n)==3 && n)
    {
        getchar();
        char maze[20][20];
        for(int i=0;i<h;i++) fgets(maze[i],20,stdin);
        
        int cnt=0,x[maxn],y[maxn],id[maxs][maxs];
        for(int i=0;i<h;i++)
        for(int j=0;j<w;j++)
        {
            char ch=maze[i][j];
            if(ch!='#')
            {
                x[cnt]=i; y[cnt]=j;
                id[i][j]=cnt;
                if(islower(ch)) s[ch-'a']=cnt;
                else if(isupper(ch)) t[ch-'A']=cnt;
                cnt++;
            }
        }
        
        for(int i=0;i<cnt;i++)
        {
            deg[i]=0;
            for(int dir=0;dir<5;dir++)
            {
                int nx=x[i]+dx[dir];
                int ny=y[i]+dy[dir];
                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",solve());
    }
    return 0;
}

以上是关于UVa1601 The Morning after Halloween(双向bfs)的主要内容,如果未能解决你的问题,请参考以下文章

UVa1601 The Morning after Halloween(双向bfs)

The Morning after Halloween uva1601

UVA - 1601 - The Morning after Halloween

UVa1601 The Morning after Halloween (双向广度优先搜索)

UVa 1601 || POJ 3523 The Morning after Halloween (BFS || 双向BFS && 降维 && 状压)

UVA10596 Morning Walk欧拉回路