poj1915~双向bfs和bfs

本文探讨了双向BFS算法在路径查找问题上的应用,并通过代码实例展示了其在解决路径问题时的效率与便利性。通过比较单向BFS与双向BFS在时间消耗上的差异,本文揭示了双向搜索在某些场景下显著提高搜索速度的可能性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

这题说是可以用双向bfs,为了看看双向到底能多牛,我做了单向和单向

第一个图是单向bfs所花的时间:



第二个图是双向bfs所花的时间


感觉……没啥特别大的区别啊^而且双向写起来有点麻烦,我写的时候漏了好多东西


直接上双向的代码好了,这个双向还是好理解的,

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

int px[8]={-1,1,-2,2,-2,2,-1,1};  
int py[8]={-2,-2,-1,-1,1,1,2,2};  
int n,sx,sy,ex,ey,vs[M][M],ve[M][M],vt[M][M];
typedef struct 
{
	int x,y;
	int time;
}chess;

int bfs()
{
	int i,j;
	memset(ve,1,sizeof(ve));
	memset(vs,1,sizeof(vs));
	for(i=2;i<=n+1;i++)
		for(j=2;j<=n+1;j++)
			ve[i][j]=vs[i][j]=0;

	chess s,e,temp;
	queue<chess> sq,eq;

	s.time=e.time=0;    //初始化操作
	s.x=sx;s.y=sy;
	e.x=ex;e.y=ey;
	vs[s.x][s.y]=ve[e.x][e.y]=1;   //vs和ve代表s队列和e队列走过的访问标识
	vt[s.x][s.y]=vt[e.x][e.y]=0;   //vt代表走到这格所花的时间,先到的先赋值
	
	if(sx==ex&&sy==ey)   //如果一开始就相同返回0
		return 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;                 //对s队列操作
			temp.x+=px[i];
			temp.y+=py[i];
			temp.time++;
			if(vs[temp.x][temp.y]==0)       
			{
				if(ve[temp.x][temp.y]==1)      //如果自己的下一步已经被e队列走过,说明相遇
					return vt[temp.x][temp.y]+temp.time;
				
				sq.push(temp);
				vs[temp.x][temp.y]=1;
				vt[temp.x][temp.y]=temp.time;  //存储自己走到这格所花的时间   
			}
			
			//对e队列的操作与s类似,e改成s,s改成e即可
			temp=e;
			temp.x+=px[i];
			temp.y+=py[i];
			temp.time++;
			if(ve[temp.x][temp.y]==0) 
			{
				if(vs[temp.x][temp.y]==1)
					return vt[temp.x][temp.y]+temp.time;
				eq.push(temp);
				ve[temp.x][temp.y]=1;
				vt[temp.x][temp.y]=temp.time;
			}

		}
	}
	
}

int main()
{
	int t,i,j,ans;
	scanf("%d",&t);
	while(t--)
	{
		scanf("%d",&n);
		scanf("%d%d%d%d",&sx,&sy,&ex,&ey);
		sx+=2;sy+=2;ex+=2;ey+=2;   //每一点+2可以防止数组为负
		ans=bfs();
		printf("%d\n",ans);
	}
	return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值