0
点赞
收藏
分享

微信扫一扫

poj2243~双向bfs


poj2243~双向bfs_双向bfs

感觉双向bfs真是麻烦,看来有必要保存这个模板!总是会遗漏好多东西!

#include<iostream>
#include<string>
#include<queue>
#define M 12
using namespace std;

int dir[8][2]={{-2,-1},{-2,1},{2,-1},{2,1},{-1,-2},{-1,2},{1,-2},{1,2}};

typedef struct
{
int x,y,t;
}knight;

int vs[M][M],ve[M][M],T[M][M];

int bfs(int sx,int sy,int ex,int ey)
{
int i,j;
memset(vs,1,sizeof(vs));
memset(ve,1,sizeof(ve));
for(i=2;i<=9;i++)
for(j=2;j<=9;j++)
vs[i][j]=ve[i][j]=0; //地图初始化,为了防止下标减2时越界,地图坐标从2到9

queue<knight> sq,eq; //sq指从起点出发的队列,eq指从终点出发的队列
knight s,e,temp;
s.x=sx; s.y=sy;
e.x=ex; e.y=ey;
s.t=e.t=0;
vs[sx][sy]=ve[ex][ey]=1;
if(sx==ex&&sy==ey) //如果在同一点直接返回0
{
return 0;
}
T[sx][sy]=T[ex][ey]=0;
sq.push(s);
eq.push(e);

while(1)
{
s=sq.front(); sq.pop();
e=eq.front(); eq.pop();

for( i=0;i<8;i++)
{
temp=s; //对sq队列操作
temp.x+=dir[i][0];
temp.y+=dir[i][1];
if(vs[temp.x][temp.y]==0) //如果下一个坐标未被sq队列访问过,则进行入队操作
{
vs[temp.x][temp.y]=1; //添加访问标记
temp.t++; //步数加1

if(ve[temp.x][temp.y]==0) //如果下一个坐标未被eq队列访问过,
T[temp.x][temp.y]=temp.t; //则对那个坐标的T值赋值
else //若被eq访问过,说明相遇了,返回答案
return T[temp.x][temp.y]+temp.t;
sq.push(temp);
}
//下面的类似,将e换为s,s换为e
temp=e;
temp.x+=dir[i][0];
temp.y+=dir[i][1];
if(ve[temp.x][temp.y]==0)
{
ve[temp.x][temp.y]=1;
temp.t++;
if(vs[temp.x][temp.y]==0)
T[temp.x][temp.y]=temp.t;
else return T[temp.x][temp.y]+temp.t;
eq.push(temp);
}
}

}

}

int main()
{
int sx,sy,ex,ey;
char sc,ec;
while(scanf("%c%d %c%d",&sc,&sy,&ec,&ey)!=EOF)
{
sx=sc-'a'+2;
ex=ec-'a'+2;
sy+=1;
ey+=1;
printf("To get from %c%d to %c%d takes %d knight moves.\n",sc,sy-1,ec,ey-1,bfs(sx,sy,ex,ey));
getchar();
}
return 0;
}



举报

相关推荐

0 条评论