首页 > 其他 > 详细

UVA-1601 The Morning after Halloween(BFS)

时间:2015-09-28 20:44:00      阅读:615      评论:0      收藏:0      [点我收藏+]

题目大意:在一张图中,以最少的步数将a,b,c移到对应的A,B,C上去。其中,每个2x2的方格都有障碍并且不能两个小写字母同时占据一个格子。

题目分析:为避免超时,先将图中所有能联通的空格建起一张图,然后再BFS。

 

代码如下:

# include<iostream>
# include<cstdio>
# include<queue>
# include<cstring>
# include<algorithm>
using namespace std;

struct Node
{
    int t,now[3];
    Node(int _t,int a=-1,int b=-1,int c=-1):t(_t){now[0]=a,now[1]=b,now[2]=c;}
    bool operator < (const Node &a) const {
        return t>a.t;
    }
};
struct Edge
{
    int to,nxt;
};
Edge e[2000];
char mp[17][17];
int w,h,n,cnt,head[267];
int goal[3],start[3],vis[268][268][268];
int d[5][2]={{0,0},{-1,0},{1,0},{0,1},{0,-1}};

void add(int u,int v)
{
    e[cnt].to=v;
    e[cnt].nxt=head[u];
    head[u]=cnt++;
}

void init()
{
    cnt=0;
    memset(start,-1,sizeof(start));
    memset(goal,-1,sizeof(goal));
    memset(head,-1,sizeof(head));
    for(int i=0;i<h;++i){
        for(int j=0;j<w;++j){
            if(mp[i][j]==‘#‘)
                continue;
            if(mp[i][j]>=‘a‘&&mp[i][j]<=‘c‘)
                start[mp[i][j]-‘a‘]=i*w+j;
            if(mp[i][j]>=‘A‘&&mp[i][j]<=‘C‘)
                goal[mp[i][j]-‘A‘]=i*w+j;
            for(int k=0;k<5;++k){
                int ni=i+d[k][0],nj=j+d[k][1];
                if(ni>=0&&ni<h&&nj>=0&&nj<w&&mp[ni][nj]!=‘#‘)
                    add(i*w+j,ni*w+nj);
            }
        }
    }
}

bool ok(const Node &u)
{
    for(int i=0;i<n;++i)
        if(u.now[i]!=goal[i])
            return false;
    return true;
}

int bfs()
{
    priority_queue<Node>q;
    memset(vis,0,sizeof(vis));
    vis[start[0]+10][start[1]+10][start[2]+10]=1;
    q.push(Node(0,start[0],start[1],start[2]));
    while(!q.empty())
    {
        Node u=q.top();
        q.pop();

        if(ok(u))
            return u.t;
        if(n==1){
            for(int i=head[u.now[0]];i!=-1;i=e[i].nxt){
                Node nxt=u;
                nxt.now[0]=e[i].to;
                if(vis[nxt.now[0]+10][nxt.now[1]+10][nxt.now[2]+10])    continue;
                vis[nxt.now[0]+10][nxt.now[1]+10][nxt.now[2]+10]=1;
                nxt.t=u.t+1;
                q.push(nxt);
            }
        }else if(n==2){
            for(int i=head[u.now[0]];i!=-1;i=e[i].nxt){
                Node nxt=u;
                nxt.now[0]=e[i].to;
                for(int j=head[u.now[1]];j!=-1;j=e[j].nxt){
                    nxt.now[1]=e[j].to;
                    if(nxt.now[0]==nxt.now[1])  continue;
                    if(nxt.now[0]==u.now[1]&&nxt.now[1]==u.now[0])    continue;
                    if(vis[nxt.now[0]+10][nxt.now[1]+10][nxt.now[2]+10])    continue;
                    vis[nxt.now[0]+10][nxt.now[1]+10][nxt.now[2]+10]=1;
                    nxt.t=u.t+1;
                    q.push(nxt);
                }
            }
        }else{
            for(int i=head[u.now[0]];i!=-1;i=e[i].nxt){
                Node nxt=u;
                nxt.now[0]=e[i].to;
                for(int j=head[u.now[1]];j!=-1;j=e[j].nxt){
                    nxt.now[1]=e[j].to;
                    if(nxt.now[0]==nxt.now[1])  continue;
                    if(nxt.now[0]==u.now[1]&&nxt.now[1]==u.now[0])    continue;
                    for(int k=head[u.now[2]];k!=-1;k=e[k].nxt){
                        nxt.now[2]=e[k].to;
                        if(nxt.now[2]==nxt.now[0]||nxt.now[2]==nxt.now[1])  continue;
                        if(nxt.now[2]==u.now[0]&&nxt.now[0]==u.now[2])  continue;
                        if(nxt.now[2]==u.now[1]&&nxt.now[1]==u.now[2])  continue;
                        if(vis[nxt.now[0]+10][nxt.now[1]+10][nxt.now[2]+10])    continue;
                        vis[nxt.now[0]+10][nxt.now[1]+10][nxt.now[2]+10]=1;
                        nxt.t=u.t+1;
                        q.push(nxt);
                    }
                }
            }
        }
    }
}

int main()
{
    while(scanf("%d%d%d",&w,&h,&n)&&(w+h+n))
    {
        getchar();
        for(int i=0;i<h;++i)
            gets(mp[i]);
        init();
        printf("%d\n",bfs());
    }
    return 0;
}

  

UVA-1601 The Morning after Halloween(BFS)

原文:http://www.cnblogs.com/20143605--pcx/p/4844828.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!