hdu1728广搜

BFS+标记最小转弯次数
http://blog.csdn.net/zhuhuangjian/article/details/8262561
http://www.cnblogs.com/g0feng/archive/2012/09/02/2667644.html
这题的解法就是对四个方向 BFS, 但不是一步一步 ,
也就是搜一个方向的时候一直搜索到沿这个方向能走到的尽头 ,
这样搜的话 , 能够保证搜过的路径的转弯次数都是最小的

#include<stdio.h>
#include<queue>
#include<string.h>  
#include<queue> 
#include<algorithm>  
using namespace std;
struct node
{
	int x,y,k;//k存拐弯数
};
int dx[]={0,0,-1,1};
int dy[]={1,-1,0,0};
char map[109][109];
int vis[109][109];
int k,n,m;
void bfs(node vs,node vd)
{    
    int flag=0;
    queue<node>q;
    node vn,vw;
    vn.x=vs.x;
	vn.y=vs.y;
	vn.k=-1;//-1,不是0
	vis[vs.x][vs.y]=1;
	q.push(vn);//push 压栈,使起点成为栈顶的第一个元素
	while(!q.empty())
	{
		vn=q.front();//front 返回队首指针
		q.pop();  //pop 弹栈,删除栈顶元素
		if(vn.x==vd.x&&vn.y==vd.y&&vn.k<=k)
		{
			flag=1;break;
		}
		vw.k=vn.k+1;
		//因为前面搜完了一个方向,就肯定会拐弯,所以要+1,也因此起点的k初始化为-1; 
		for(int i=0;i<4;i++)
		{   
		    int a=vn.x+dx[i];int b=vn.y+dy[i];
			while(a>=0&&a<n&&b>=0&&b<m&&map[a][b]!='*')//搜完一个方向
			{
				if(!vis[a][b])//没访问过就加入队列
				{  
				    vis[a][b]=1;
					vw.x=a;vw.y=b;
					q.push(vw);
				}
				a=a+dx[i];b=b+dy[i];//搜完一个方向
			}
		}
	}
	if(flag==1) printf("yes\n");
	else printf("no\n");
}
int main()
{  int t,i,x1,x2,y1,y2;
	scanf("%d",&t);
	while(t--)
	{  
		memset(vis,0,sizeof(vis));
	    node vs,vd;
		scanf("%d%d",&n,&m);
		for(i=0;i<n;i++)
		scanf("%s",map[i]);
		scanf("%d%d%d%d%d",&k,&y1,&x1,&y2,&x2);
		//注意他说的行列和常规的想法不一样,免得自己搞混,所以我先输入的y。
		vs.x=x1-1;vs.y=y1-1;vd.x=x2-1;vd.y=y2-1;
		bfs(vs,vd);
	}
}

 

posted @ 2013-04-14 15:38  宛如  阅读(164)  评论(0编辑  收藏  举报