一,深度优先搜索
1.基本概念
深度优先搜索算法(Depth First Search,简称DFS):是一种用于遍历或搜索树或图的算法。 沿着树的深度遍历树的节点,尽可能深的搜索树的分支。当节点v的所在边都己被探寻过或者在搜寻时结点不满足条件,搜索将回溯到发现节点v的那条边的起始节点。整个进程反复进行直到所有节点都被访问为止。属于盲目搜索,最糟糕的情况算法时间复杂度为O(!n)。
2.搜索步骤
(1)首先找到初始节点V0
(2)依此从V0未被访问的邻接点出发,对图进行深度优先遍历
(3)若有节点未被访问,则回溯到该节点,继续进行深度优先遍历
(4)直到所有与顶点V0路径想通的节点都被访问过一次
举个例子,假设我们要从起始点V0出发,使用深度优先搜索算法进行搜索,首先访问V0->V1->V4,走不通了,回溯到上一个结点V1,走V1分支节点V2,路径为V0->V1->V2->V6,走不通了,再回溯到V2,发现没有分支结点,继续回溯到V1,走下一个分支结点V3,然后继续向下搜索。
3.基本模板
void dfs(int step)
{
if (满足输出条件)
{
for (int i = 1; i <= n; i++) {
printf(" 输出解");
}
printf("\n");
}
else
{
for (int i = 1; i <= ; i++) {
if (满足进一步搜索条件)
{
为进一步搜索所需要的状态做标记;
dfs(step + 1);
恢复到打标记前的状态; //用于回溯到上一步
}
}
}
}
二、P1219 [USACO1.5]八皇后 Checker Challenge
代码如下(示例):
//此代码以
#include<stdio.h>
int a[100], b[100], c[100], d[100];
//a数组表示的是行;
//b数组表示的是列;
//c表示的是左下到右上的对角线;
//d表示的是左上到右下的对角线;
int total;//总数
int n;
void dfs(int i)//搜索与回溯主体
{
if (i > n)
{
if (total <= 2)//保证只输出前三个解,如果解超出三个就不再输出
{
for (int k = 1; k <= n; k++)
printf("%d ", a[k]);//打印前三个解
printf("\n");
}
total++;//计算一共有多少种解法
return;
}
else
{
for (int j = 1; j <= n; j++)//
{
if ((!b[j]) && (!c[i + j]) && (!d[i - j + n]))
//确定某一个格子的列和两个对角线都没有被占领,一行一行遍历
{
a[i] = j; //标记第i排被占领的位置上,用于遍历输出结果
b[j] = 1; //标记占领纵列
c[i + j] = 1; //标记对角线,i+j是这一列对角线共同的特点
d[i - j + n] = 1;
dfs(i + 1);//进一步搜索,下一个皇后
b[j] = 0;
c[i + j] = 0;
d[i - j + n] = 0;
//清除标记,回到上一步重新寻找另一种路线
}
}
}
}
int main()
{
scanf("%d", &n);
dfs(1);//第一个皇后
printf("%d", total);//输出可能的总数
return 0;
}