DFS( Depth-First-Search ) 深度优先搜索算法 :
深度优先搜索算法是图论的基础算法,在介绍DFS之前,我们先来介绍一下什么是深度优先搜索:
一、DFS概念:
正如算法名称那样,深度优先搜索所遵循的搜索策略是尽可能“深”地搜索图。
在深度优先搜索中,对于最新发现的顶点,如果它还有以此为起点而未探测到的边,就沿此边继续汉下去。
这一过程一直进行到已发现从源结点可达的所有结点为止,整个进程反复进行直到所有结点都被发现为止。
二、DFS分类:
对于解决问题的不同,分为:回溯法和非回溯法;
①. 非回溯法 : 对于图中的路线,仅搜索一次,之后不再搜索;
例 : 计算一片土地中满足条件的最大的一片土地;
②. 回溯法 :对于图中的路线,不止搜索一次,每次搜索之后,为了下一次路线,都要将图复原;
例 : 计算最短的行走路线问题;
三、DFS算法的实现:
1. 作为图论,首先我们需要定义一个 m x n 的地图 map[ M ][ N ]来存储地图[ 通常为二维空间 ],和 x,y作为坐标;
2. DFS函数:
void fun(int x,int y)
{
if(x<1||x>m||y<1||y>n) return;
if(map[x][y]==0) return;
if(map[x][y]==1)
{
map[x][y]=0;
num++;
fun(x-1,y);
fun(x+1,y);
fun(x,y-1);
fun(x,y+1);
}
}
①. 第一个if : 若左边在图像之外,不满足条件,返回;
②. 第二个if : 如果碰到不满足条件的点[ 这里用 ‘0’ 表示 ],返回;
③. 如果是 ‘1’ [ 满足条件的点 ],将其标记为已经走过的点,并向处该点之外的其他四个方向搜索;
2、回溯法 :
void fun(int x,int y)
{
if(x<1||x>m||y<1||y>n) return;
if(map[x][y]=='0') return;
map[x][y]='0';
snum++;
fun(x-1,y);
fun(x+1,y);
fun(x,y-1);
fun(x,y+1);
snum--;
map[x][y]='1';
}
①. 前面都是一样的;
②. 只需要在函数后,加 map[ x ][ y ]=' 1 ' , 即可;
例题:
Oil Deposits
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 18604 Accepted Submission(s): 10719
1 1 * 3 5 *@*@* **@** *@*@* 1 8 @@****@* 5 5 ****@ *@@*@ *@**@ @@@*@ @@**@ 0 0
0 1 2 2
@代表油田,相临的@一共算一大片油田,问总共有多少片油田;
题目分析:
1. 从左上角开始搜索,将某一片能搜索的油田都赋予 ‘* ’ ,并且数量加一;
2. 一直搜索到地图结束( 右下角 );
AC代码:
#include<stdio.h>
#include<string.h>
#include<math.h>
char map[110][110];
int m,n,count;
void fun(int x,int y)
{
if(x<1||x>m||y<1||y>n) return;
if(map[x][y]=='*') return;
map[x][y]='*';
fun(x-1,y);
fun(x+1,y);
fun(x,y+1);
fun(x,y-1);
fun(x+1,y+1);
fun(x-1,y+1);
fun(x-1,y-1);
fun(x+1,y-1);
}
int main()
{
while(scanf("%d%d",&m,&n),m|n)
{
count=0;
int i,j;
for(i=1; i<=m; i++)
for(j=1; j<=n; j++)
scanf(" %c",&map[i][j]);
while(1)
{
for(i=1; i<=m; i++)
for(j=1; j<=n; j++)
if(map[i][j]=='@')
{
fun(i,j);
count++;
}
if(i==m+1&&j==n+1) break;
}
printf("%d\n",count);
}
return 0;
}
在做DFS的时候要注意,许多变量要定义为全局变量,否则无法存储结果;