不恋尘世浮华,不写红尘纷扰,不叹世道苍凉,不惹情思哀怨,闲看花开,静待花落,冷暖自知,干净如始。
从谁开始就把谁存到队列里,从它开始进行以后的步骤,广搜的话会遇到许多分支一类的东西,每遇到一个分支就要push进队列里,每次处理判断时都要处理最前边的,即front(),处理的同时也要将其删掉pop(),方便可以一直处理front()的那个。在处理的过程中也要判断找寻是否是结果,进行判断。。。。进行广搜要灵活将struct与queue结合使用,化繁为简。
广搜适用于最短最小问题,先搜到的路径一定是最小的。
特点:
(1)在产生新的子结点时,深度越小的结点越先得到扩展,即先产生它的子结点。为使算法便于实现,存放结点的数据库一般用队列的结构。
(2)无论问题性质如何不同,利用广度优先搜索法解题的基本算法是相同的,但数据库中每一结点内容,产生式规则,根据不同的问题,有不同的内容和结构,就是同一问题也可以有不同的表示方法。
(3)当结点到跟结点的费用(有的书称为耗散值)和结点的深度成正比时,特别是当每一结点到根结点的费用等于深度时,用广度优先法得到的解是最优解,但如果不成正比,则得到的解不一定是最优解。这一类问题要求出最优解,一种方法是使用后面要介绍的其他方法求解,另外一种方法是改进前面深度(或广度)优先搜索算法:找到一个目标后,不是立即退出,而是记录下目标结点的路径和费用,如果有多个目标结点,就加以比较,留下较优的结点。把所有可能的路径都搜索完后,才输出记录的最优路径。(4)广度优先搜索算法,一般需要存储产生的所有结点,占的存储空间要比深度优先大得多,因此程序设计中,必须考虑溢出和节省内存空间得问题。
(5)广度优先搜索法一般无回溯操作,即入栈和出栈的操作,所以运行速度比深度优先搜索算法法要快些。
(其实吧,我觉得它最大的特点就是代码冗长,但是该会的还是得会,就这一块我迷了好一阵,还是先把模板给背了呢)
下面就贴几个例题吧,首先是用深搜做的那个迷宫问题。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<iomanip>
#include<algorithm>
using namespace std;
int a[100][100],book[100][100];
int fx[4][2]={{0,1},{1,0},{0,-1},{-1,0}};
struct node
{
int x;
int y;
int f;//这是用来输出路径的,此题没要求可以不写
int s;
};
int main()
{
struct node q[2501];
int head,tail;
int i,j,k,n,m,csx,csy,zdx,zdy,tx,ty,flag;
cin>>n>>m;
for(i=1;i<=n;i++)
for(j=1;j<=m;j++)
cin>>a[i][j];
cin>>csx>>csy>>zdx>>zdy;
head=1;
tail=1;
q[tail].x=csx;
q[tail].y=csy;
q[tail].f=0;
q[tail].s=0;
tail++;
book[csx][csy]=1;
flag=0;
while(head<tail)
{
for(k=0;k<4;k++)
{
tx=q[head].x+fx[k][0];
ty=q[head].y+fx[k][1];
if(tx>n||ty>m||tx<=0||ty<=0)
continue;
if(a[tx][ty]==0&&book[tx][ty]==0)
{
book[tx][ty]=1;
q[tail].x=tx;
q[tail].y=ty;
q[tail].f=head;
q[tail].s=q[head].s+1;
tail++;
}
if(tx==zdx&&ty==zdy)
{
flag=1;
break;
}
}
if(flag==1)
break;
head++;
}
cout<<q[tail-1].s;
return 0;
}
#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<iomanip>
#include<algorithm>
using namespace std;
char a[25][25];
int fx[4][2]={{0,1},{1,0},{0,-1},{-1,0}};
struct node
{
int x;
int y;
};
int getnum(int i,int j)
{
int sum,x,y;
sum=0;//7用来计数
x=i;
y=j;
while(a[x][y]!='#')
{
if(a[x][y]=='G')
sum++;
x--;
}
x=i;
y=j;
while(a[x][y]!='#')
{
if(a[x][y]=='G')
sum++;
x++;
}
x=i;
y=j;
while(a[x][y]!='#')
{
if(a[x][y]=='G')
sum++;
y--;
}
x=i;
y=j;
while(a[x][y]!='#')
{
if(a[x][y]=='G')
sum++;
y++;
}
return sum;
}
int main()
{
struct node q[401];
int head,tail;
int book[20][20]={0};
int i,j,k,n,m,mx,my,csx,csy,sum,ma=0,tx,ty;
cin>>n>>m>>csx>>csy;
for(i=0;i<n;i++)
scanf("%s",a[i]);
head=1;
tail=1;
q[tail].x=csx;
q[tail].y=csy;
tail++;
book[csx][csy]=1;
ma=getnum(csx,csy);
mx=csx;
my=csy;
while(head<tail)
{
for(k=0;k<4;k++)
{
tx=q[head].x+fx[k][0];
ty=q[head].y+fx[k][1];
if(tx>n||ty>m||tx<=0||ty<=0)
continue;
if(a[tx][ty]=='.'&&book[tx][ty]==0)
{
book[tx][ty]=1;
q[tail].x=tx;
q[tail].y=ty;
tail++;
sum=getnum(tx,ty);
if(sum>ma)
{
ma=sum;
mx=tx;
my=ty;
}
}
}
head++;
}
printf("将炸弹放到(%d,%d)处,可以消灭%d个敌人\n",mx,my,ma);
return 0;
}
/*13 13 3 3
#############
#GG.GGG#GGG.#
###.#G#G#G#G#
#.......#..G#
#G#.###.#G#G#
#GG.GGG.#.GG#
#G#.#G#.#.#.#
##G...G.....#
#G#.#G###.#G#
#...G#GGG.GG#
#G#.#G#G#.#G#
#GG.GGG#G.GG#
#############
运行结果:
将炸弹放到(7,11)处,可以消灭10个敌人*/