0x25 广度优先搜索

Posted akcqhzdy

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了0x25 广度优先搜索相关的知识,希望对你有一定的参考价值。

今天莫名不想说话。

结果发现效率挺高?

 

poj3322 本来可以1a的。。发现我宽搜写的是head<=tail而且初始是head=1,tail=2如果是多组数据简直就gg了。基础不牢固

这题虽然看起来麻烦,但是实际上仔细思考一下是不难推出对于各种不同放在地图上的方式分别表示的。

技术分享图片
#include<cstdio>
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<cmath>
using namespace std;
const int dx[4]={-1,0,1,0};
const int dy[4]={0,-1,0,1};

int n,m;
char ss[510][510];
struct node
{
    int x,y,l,c;
}list[1100000];
bool check(int x,int y){return 0<x&&x<=n&&0<y&&y<=m&&ss[x][y]!=#;}

bool v[510][510][3];
int main()
{
    int stx,sty,stl,edx,edy,edl;bool sb;
    while(scanf("%d%d",&n,&m)!=EOF)
    {
        if(n==0&&m==0)break;
        
        sb=false;
        for(int i=1;i<=n;i++)scanf("%s",ss[i]+1);
        for(int i=1;i<=n;i++)
        {
            for(int j=1;j<=m;j++)
                if(ss[i][j]==X&&sb==false)
                {
                    sb=true;
                    stx=i, sty=j;
                         if(ss[i+1][j]==X)stl=1;
                    else if(ss[i][j+1]==X)stl=2;
                    else stl=0;
                }
                else if(ss[i][j]==O) edx=i, edy=j;
        }
        memset(v,false,sizeof(v));
        for(int i=1;i<=1000000;i++)list[i].x=list[i].y=list[i].l=list[i].c=0;
        list[1].x=stx;list[1].y=sty;list[1].l=stl;list[1].c=0;
        int head=1,tail=2;
        while(head<=tail)
        {
            if(list[head].x==edx&&list[head].y==edy&&list[head].l==0)
            {
                printf("%d
",list[head].c);
                break;
            }
            
            for(int k=0;k<=3;k++)
            {
                node tno=list[head];tno.c++;
                if(tno.l==0)
                {
                    tno.x+=dx[k]<0?dx[k]*2:dx[k];
                    tno.y+=dy[k]<0?dy[k]*2:dy[k];
                    tno.l=dx[k]==0?2:1;
                }
                else if(tno.l==1)
                {
                    tno.x+=dx[k]>0?dx[k]*2:dx[k];
                    tno.y+=dy[k];
                    tno.l=dx[k]==0?1:0;
                }
                else if(tno.l==2)
                {
                    tno.x+=dx[k];
                    tno.y+=dy[k]>0?dy[k]*2:dy[k];
                    tno.l=dy[k]==0?2:0;
                }
                
                if(check(tno.x,tno.y))
                {
                    if(tno.l==0&&ss[tno.x][tno.y]==E)continue;
                    if(tno.l==1&&!check(tno.x+1,tno.y))continue;
                    if(tno.l==2&&!check(tno.x,tno.y+1))continue;
                    if(v[tno.x][tno.y][tno.l]==false)
                    {
                        v[tno.x][tno.y][tno.l]=true;
                        list[tail]=tno;
                        tail++;
                    }
                }
            }
            head++;
        }
        if(!v[edx][edy][0])printf("Impossible
");
    }
    return 0;
}
poj3322

bzoj2252 又是gb权限题。。可以说是相当简单,让1去找0,直到全图被访问过

技术分享图片
#include<cstdio>
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<cmath>
using namespace std;
const int dx[4]={-1,0,1,0};
const int dy[4]={0,-1,0,1};

struct node
{
    int x,y;
}list[1100000];
int d[1100][1100];

char ss[1100];
int main()
{
    int n,m,cnt;
    scanf("%d%d",&n,&m);cnt=n*m;
    
    int head=1,tail=2;
    memset(d,-1,sizeof(d));
    for(int i=1;i<=n;i++)
    {
        scanf("%s",ss+1);
        for(int j=1;j<=m;j++)
        {
            if(ss[j]==1)
            {
                d[i][j]=0;
                list[tail].x=i,list[tail].y=j;
                tail++;
            }
        }
    }
    
    while(head<=tail)
    {
        int x=list[head].x,y=list[head].y;
        for(int k=0;k<=3;k++)
        {
            int tx=x+dx[k],ty=y+dy[k];
            if(0<tx&&tx<=n&&0<ty&&ty<=m&&d[tx][ty]==-1)
            {
                d[tx][ty]=d[x][y]+1;
                list[tail].x=tx,list[tail].y=ty;
                tail++;
            }
        }
        head++;
    }
    
    for(int i=1;i<=n;i++)
    {
        for(int j=1;j<m;j++)
            printf("%d ",d[i][j]);
        printf("%d
",d[i][m]);
    }
    return 0;
}
bzoj2252

poj1475 码量大而且麻烦,这种题是需要沉下心做的。先bfs让人到箱子周边,再让箱子bfs,实际上就是bfs套bfs,人和箱子绑成一块,记得算答案是有四种不同情况的。

技术分享图片
#include<cstdio>
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<cmath>
using namespace std;
const int dx[4]={-1,0,1,0};
const int dy[4]={0,-1,0,1};
const char ch[4]={N,W,S,E};

int n,m;
char sc[30][30];
struct node
{
    int x,y,k;
}list[410000];
int d[30][30][4],f[30][30][4];
char ss[30][30][4][1100];


int xx[3100],yy[3100];
int E[30][30];
char sd[30][30][1100];
bool check(int x,int y){return 0<x&&x<=n&&0<y&&y<=m&&sc[x][y]!=#;}
int getdis(int stx,int sty,int edx,int edy,int k)
{
    memset(E,-1,sizeof(E));
    xx[1]=stx,yy[1]=sty;E[stx][sty]=0;
    int head=1,tail=2;
    while(head<tail)
    {
        int x=xx[head],y=yy[head];
        if(x==edx&&y==edy)return E[x][y];
        for(int i=0;i<=3;i++)
        {
            int tx=x+dx[i],ty=y+dy[i];
            if(check(tx,ty)&&(tx!=edx+dx[k]||ty!=edy+dy[k])&&E[tx][ty]==-1)
            {
                for(int o=1;o<=E[x][y];o++)sd[tx][ty][o]=sd[x][y][o];
                sd[tx][ty][E[x][y]+1]=ch[i]+32;
                E[tx][ty]=E[x][y]+1;
                
                xx[tail]=tx,yy[tail]=ty;
                tail++;
            }
        }
        head++;
    }
    return -1;
}
int main()
{
//    freopen("a.out","w",stdout);
    int T_T=0;
    while(scanf("%d%d",&n,&m)!=EOF)
    {
        if(n==0&&m==0)break;
        printf("Maze #%d
",++T_T);
        
        int stpx,stpy,stbx,stby,edx,edy;
        for(int i=1;i<=n;i++)
        {
            scanf("%s",sc[i]+1);
            for(int j=1;j<=m;j++)
                     if(sc[i][j]==S) stpx=i, stpy=j;
                else if(sc[i][j]==B) stbx=i, stby=j;
                else if(sc[i][j]==T) edx=i, edy=j;
        }
        
        int head=1,tail=1;
        memset(d,-1,sizeof(d));
        for(int i=0;i<=3;i++)
        {
            int ux=stbx+dx[i],uy=stby+dy[i];
            if(check(ux,uy))
            {
                int dis=getdis(stpx,stpy,ux,uy,(i+2)%4);
                if(dis==-1)continue;
                
                for(int o=1;o<=dis;o++)ss[stbx][stby][i][o]=sd[ux][uy][o];
                d[stbx][stby][i]=0;
                f[stbx][stby][i]=dis;
                
                list[tail].x=stbx,list[tail].y=stby,list[tail].k=i;
                tail++;
            }
        }
        bool bk=false;int id=-1,cnt=0;
        while(head<tail)
        {
            int x=list[head].x,y=list[head].y,k=list[head].k;
            if(x==edx&&y==edy)
            {
                if(id==-1||(d[x][y][k]<d[x][y][id]||(d[x][y][k]==d[x][y][id]&&f[x][y][k]<f[x][y][id])))
                {
                    id=k;
                    cnt++;if(cnt==4)break;
                    bk=true;
                }
            }
            
            int px=x+dx[k],py=y+dy[k];
            for(int i=0;i<=3;i++)
            {
                int ux=x+dx[i],uy=y+dy[i];
                int tx=x-dx[i],ty=y-dy[i];
                if(check(tx,ty)&&check(ux,uy)&&(d[tx][ty][i]==-1||d[x][y][k]+1==d[tx][ty][i]))
                {
                    int dis=getdis(px,py,ux,uy,(i+2)%4);
                    if(dis==-1||(d[x][y][k]+1==d[tx][ty][i]&&f[x][y][k]+dis>=f[tx][ty][i]))continue;
                    
                    int tot=d[x][y][k]+f[x][y][k];
                    for(int o=1;o<=tot;o++)ss[tx][ty][i][o]=ss[x][y][k][o];
                    for(int o=1;o<=dis;o++)ss[tx][ty][i][tot+o]=sd[ux][uy][o];
                    ss[tx][ty][i][tot+dis+1]=ch[(i+2)%4];
                    
                    d[tx][ty][i]=d[x][y][k]+1;
                    f[tx][ty][i]=f[x][y][k]+dis;
                    
                    list[tail].x=tx,list[tail].y=ty,list[tail].k=i;
                    tail++;
                }
            }
            head++;
        }
        if(bk==false)printf("Impossible.

");
        else
        {
            for(int o=1;o<=d[edx][edy][id]+f[edx][edy][id];o++)printf("%c",ss[edx][edy][id][o]);
            printf("

");
        }
    }
    return 0;
}
poj1475

 

以上是关于0x25 广度优先搜索的主要内容,如果未能解决你的问题,请参考以下文章

《算法竞赛进阶指南》0x25广度优先搜索 推箱子游戏 双重BFS

基础扩展 | 16. 队列应用示例:广度优先搜索

广度优先搜索算法(go)

Prolog中的广度优先搜索

面试题算法: 广度优先搜索

图相关算法