【dfs(深搜)模板】

深度优先搜索是图论中的经典算法,英文缩写为DFS即Depth First Search.其过程简要来说是对每一个可能的分支路径深入到不能再深入为止,而且每个节点只能访问一次.
正如算法名称那样,深度优先搜索所遵循的搜索策略是尽可能"深"地搜索图。在深度优先搜索中,对于最新发现的顶点,如果它还有以此为起点而未探测到的边,就沿此边继续汉下去。当结点v的所有边都己被探寻过,搜索将回溯到发现结点v有那条边的始结点。这一过程一直进行到已发现从源结点可达的所有结点为止。如果还存在未被发现的结点,则选择其中一个作为源结点并重复以上过程,整个进程反复进行直到所有结点都被发现为止。
效率:
作为搜索算法的一种,DFS对于寻找一个解的NP(包括NPC)问题作用很大。但是,搜索算法毕竟是时间复杂度是O(n!)的阶乘级算法,它的效率比较低,在数据规模变大时,这种算法就显得力不从心了。

关于深度优先搜索的效率问题,有多种解决方法。最具有通用性的是剪枝(prunning),也就是去除没有用的搜索分支。有可行性剪枝和最优性剪枝两种。


代码:

#include<cstdio>
#include<queue>
#include<cstring>
#include<algorithm>
using namespace std;
struct Node
{
	int x,y;
	int step;
}pr,ne;
int h,w;
int st_x,st_y,endd_x,endd_y;
char mapp[50][50];
int mx[4] = {0,0,1,-1}; //向上下左右四个方向移动;(0,1)(0,-1)(1,0)(-1,0)
int my[4] = {1,-1,0,0};

bool check(int x,int y)   //判断是否满足条件的子函数;
{
	if (x < 0 || y < 0 || x >= h || y >= w || mapp[x][y] == '#')
		return false;
	return true;
}

bool dfs(int x,int y)
{
	if (x == endd_x && y == endd_y)
		return true;
	mapp[x][y] = '#';
	for (int i = 0 ; i < 4 ; i++)
	{
		if (check(x+mx[i],y+my[i]))
		{
			if (dfs(x+mx[i],y+my[i]))
				return true;
		}
	}
	return false;
}

int main()
{
	scanf ("%d %d",&h,&w);
	for (int i = 0 ; i < h ; i++)
	{
		scanf ("%s",mapp[i]);
		for (int j = 0 ; j < w ; j++)
		{
			if (mapp[i][j] == '@')
			{
				st_x = i;
				st_y = j;
			}
			else if (mapp[i][j] == '!')
			{
				endd_x = i;
				endd_y = j;
			}
		}
	}
	printf ("%s\n",dfs(st_x,st_y) ? "YES" : "NO");
	return 0;
}


DFS(Depth-First Search)即深度优先搜索,是一种常用的图遍历算法。在DFS中,我们从图的某个顶点开始,沿着一条路径尽可能深的搜索,直到无法继续为止,然后回溯到前一个节点,再继续搜索其他未访问的节点。 在C++中,我们可以使用递归或者栈来实现DFS算法。下面是一个使用递归实现DFS的示例代码: ```cpp #include <iostream> #include <vector> using namespace std; vector<vector<int>> graph; // 图的邻接表表示 vector<bool> visited; // 记录节点的访问状态 // 深度优先搜索函数 void dfs(int node) { visited[node] = true; // 标记当前节点为已访问 // 对于当前节点的所有未访问的邻居节点,递归调用dfs函数 for (int neighbor : graph[node]) { if (!visited[neighbor]) { dfs(neighbor); } } } int main() { int numNodes, numEdges; cin >> numNodes >> numEdges; // 初始化图的邻接表和访问状态数组 graph.resize(numNodes); visited.resize(numNodes, false); for (int i = 0; i < numEdges; i++) { int u, v; cin >> u >> v; graph[u].push_back(v); graph[v].push_back(u); // 若为有向图则可省略这行 } int startNode; // 指定DFS的起始节点 cin >> startNode; dfs(startNode); // 输出所有已访问的节点 for (int i = 0; i < numNodes; i++) { if (visited[i]) { cout << i << " "; } } cout << endl; return 0; } ``` 在上述代码中,我们通过邻接表来表示图,并使用visited数组记录节点的访问状态。dfs函数按照深度优先的方式遍历图,递归调用自身来访问当前节点的邻居节点。最后,我们输出所有已访问的节点。 需要注意的是,DFS算法对于有环的图需要进行环的检测,以避免无限循环。另外,如果图是一个森林(由多个连通分量组成),我们需要对每个连通分量都执行DFS算法。 希望这个示例能帮助你理解DFS在C++中的实现。如果有任何疑问,请随时提问。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值