DFS(深搜)
1.描述:
对每一个可能的分支路径深入到不能再深为止,并且每个结点只能访问一次。
”一条路走到黑,走不了再倒回去“
2.算法过程:
描述1:void dfs(状态)
1.判断当前状态是否合法,合法则继续执行,否则则回到上次调用
2.遍历每个新状态,如果新状态合法,dfs(新状态)
描述2:
1.访问顶点v;
2.依次从v的未被访问的邻接点出发,直到图中所有顶点均被访问。
3.若此图中尚有顶点未被访问,则从一个未被访问的顶点出发,直到所有顶点被访问完。
3.示例:
洛谷:p2802回家
#include<iostream>
using namespace std;
int a[10][10],v[10][10],s1,s2,step,f,n,m;
int dx[4]={0,1,0,-1};
int dy[4]={1,0,-1,0};
void dfs(int x,int y,int t,int r)
{
if(t>step||r==0)//不能回家:血量为0或死循环
{
return ;
}
if(a[x][y]==3)//能回家
{
if(t<step)//选方案中最短时间
{
step=t;
f=1;
}
return ;
}
if(a[x][y]==4)//回满血
{
r=6;
}
for(int i=0;i<4;i++)
{
int nx=x+dx[i];
int ny=y+dy[i];
if(nx<1||nx>n||ny<1||ny>m||a[nx][ny]==0||v[nx][ny]>2)
{
continue;
}
v[nx][ny]++;
dfs(nx,ny,t+1,r-1);
v[nx][ny]--;//用完复原
}
}
int main()
{
cin>>n>>m;
for(int i=1;i<=n;i++)
{
for(int j=1;j<=m;j++)
{
cin>>a[i][j];
if(a[i][j]==2)
{
s1=i,s2=j;//记录起点
}
}
}
step=n*m;//一个临界步数
v[s1][s2]++;//经过该点的次数
dfs(s1,s2,0,6);
if(f==1)
{
cout<<step<<endl;
}
else
{
cout<<"-1"<<endl;
}
return 0;
}
BFS(广搜)
1.描述: bfs属于一种盲目搜寻法,目的是系统地展开并检查图中的所有节点,以找寻结果。换句话说,它并不考虑结果的可能位置,彻底地搜索整张图,直到找到结果为止。
2.算法思想:
一层一层的走。
总是每次都把离上一状态最近的状态用一个队列记录下来。
记录之后,检查队列是否为空,如果不为空,就将队首元素弹出,并且以这个状态为“根节点”进行bfs,直到整个队列为空为止。
3.示例:
洛谷:P1443 马的遍历
#include<bits/stdc++.h>
using namespace std;
int dx[8]={2,1,-1,-2,2,1,-1,-2};//马的方向位置
int dy[8]={1,2,2,1,-1,-2,-2,-1};
struct xy //某个点的坐标
{
int x,y;
}node,top;//top存队列队首元素
int n,m,a[405][405],x,y;//a数组记录步数
bool b[405][405];//bool类型记录该点之前有没有走过
void bfs(int x,int y,int t)
{
//处理起始点
a[x][y]=0;
b[x][y]=0;
node.x=x;
node.y=y;
queue<xy> q;//建立队列
q.push(node);//将起点放入队列中
while(!q.empty())//如果队列不为空
{
top=q.front();//弹出队首点
q.pop();//将弹出的点出队
for(int i=0;i<8;i++)//从该点遍历8个方向
{
int nx=top.x+dx[i];
int ny=top.y+dy[i];
if(nx<1||nx>n||ny<1||ny>m)//如果超出边界
{
continue;
}
if(b[nx][ny])//该点之前没有被走过
{
a[nx][ny]=a[top.x][top.y]+1;
b[nx][ny]=0;
node.x=nx;
node.y=ny;
q.push(node);
}
}
}
}
int main()
{
memset(a,-1,sizeof(a));
memset(b,1,sizeof(b));//bool数组都记为1,表示没有走过
scanf("%d%d%d%d",&n,&m,&x,&y);
bfs(x,y,0);//输入起点位置和步数
for(int i=1;i<=n;i++)
{
for(int j=1;j<=m;j++)
{
printf("%-5d",a[i][j]);//输出,注意输出格式
}
printf("\n");
}
return 0;
}
注:来源为百度和牛客算法竞赛入门班笔记。
此外如有错误,欢迎指出。