杭电 rescue(经典广搜)(深搜广搜对比)

今天也终于领略到什么是深搜什么是广搜的区别和特点了,其实一直不太懂什么时候用深搜,什么时候用广搜,虽然两种都有用过,但是都是结合解题报告或者其他途径来做的,总感觉深搜用起来比较顺手,感觉很多题都可以用深搜来解决,但是今天遇到的这个题用深搜怎么想方设法都不好用,结果应该正确,但是就是TimeLimit,只好用广搜来解了,也颇费周折的各方面查资料知道了广搜一般用在有这样的提示:最短时间或者最短路径,或许这就是基本层面但很有用处的区别,现在的理解就到这里了,另外其他学术性的区别见博客:http://blog.csdn.net/u014665013/article/details/39558093


声明一下:优先队列和队列的区别,优先队列是能通过优先级来限定队列的顺序的,但是队列只能是先进先出,不能按照参数来限定顺序 ,这里用到的是优先队列


题目来源:http://acm.hdu.edu.cn/showproblem.php?pid=1242

贴一下用深搜做的TimeLimit的代码,毕竟是经过一番思考的...  从四个方向深搜..

#include 
#include 
#include 
#include 
#include 
using namespace std;
int sum=0, row,line,doorrow,doorline,startrow,startline,count=0,mark=0;
char ch[205][205]={0};
void find(int i,int j){
	if(doorrow==i&&doorline==j){ //注意最后一次到达的时候会将a还原时改为'.' ,但是不妨碍  
	   if (mark==0||sum0&&ch[i-1][j]!='#'){
	   	char temp='.';
	   	sum++;
	    if(ch[i-1][j]=='x')  sum++,temp='#';//如果是守卫,需要用1单位时间来杀掉他 
	    ch[i-1][j]='#';
	    find(i-1,j);
	    if(temp=='#') sum--,ch[i-1][j]='x'; 
	    else  ch[i-1][j]='.';
	    sum--;
	   }
   	  if(i0&&ch[i][j-1]!='#'){
   	   char temp='.';
	   sum++;
	   if(ch[i][j-1]=='x')  sum++,temp='#';
	   ch[i][j-1]='#';
	   find(i,j-1);
	   if(temp=='#') sum--,ch[i][j-1]='x'; 
	   else ch[i][j-1]='.';
	   sum--;
   	  }
   	 if(j0&&ch[i][j+1]!='#'){
   	 	char temp='.';
		sum++;
		if(ch[i][j+1]=='x')  sum++,temp='#';
		ch[i][j+1]='#';
		find(i,j+1);
		if(temp=='#') sum--,ch[i][j+1]='x'; 
	    else ch[i][j+1]='.';
		sum--;
   	  }
    }
}
int main (){
	while(~scanf("%d%d",&row,&line)){
	sum=0,mark=0,count=0;	//别忘了每次都要初始化 
	for(int i=0;i

使用广搜(使用优先级队列,因为两者好像不可分的),通过优先级队列的排序功能控制逐层进行遍历。

这里又悟出了深搜和广搜的一点不同:

现在知道为什么用宽度搜索了,(1)如果深度搜索的话,会沿着一条路径走到头,包括中间有很多分叉路,这样只有走到头才会停止本次搜索,但是宽度搜索就不一样了,他会按照层数进行查找,这样可以使一些不正确的路径不会走到头,相当于节省了这部分时间,所以相对来书效率就高了。

(2)另外深搜和广搜另外一个很大的不同好像也在于,深搜一般是递归调用函数,这样深搜;但是广搜则是没有递归调用函数,而是通过优先队列来通过循环实现的,这应该也是一个很大的不同吧

广搜代码:

#include 
#include 
#include 
#include 
#define N 201
using namespace std;
//优先队列解决,广度优先
struct Persion
{
    int x,y;
    int times;
    friend bool operator < (const Persion &a,const Persion &b)
    {
        return a.times>b.times; //">" 返回队列中较小的元素;"< " 则返回队列中较大的元素
    }
};
//这样优先级排序为小的在top(可以理解为右面是top) 
int dir[4][2]={{-1,0},{1,0},{0,-1},{0,1}};//四个方向的操作 
char map[N][N];
int visited[N][N];
int m,n;
int BFS(int x,int y)
{
    priority_queue  q; //新建优先队列 
    Persion current,next;
    
    memset(visited,0,sizeof(visited));
    
    current.x=x,current.y=y,current.times=0;
    
    visited[current.x][current.y]=1;//标记访问过了 
    q.push(current);    //当前访问的入队 
    while(!q.empty())
    {
      current=q.top();
      q.pop();    // 
      for(int i=0;i<4;i++)//对四个方向查找 
      {
         next.x=current.x+dir[i][0];
         next.y=current.y+dir[i][1];
         if( next.x>=0&&next.x=0&&next.y>n>>m&&(m||n))
    {
    for(i=0;i>map[i][j];
           if(map[i][j]=='r')
           angle.x=i,angle.y=j;
        }
    int times=BFS(angle.x,angle.y);
    if(times==-1)
       cout<<"Poor ANGEL has to stay in the prison all his life."<






你可能感兴趣的:(搜索--BFS,&,DFS)