Depth First Search

Depth First Search

题目链接

click here!

题目大意

dfs模板题,但是作为模板题可能还是要解释一下dfs到底是什么

dfs:深度优先搜索,是一种图论的遍历(搜索)策略,简单来说就是一条路走到黑,直到没办法往下继续走为止,此时会回退到上一个多分支的地方,对第二个分支重复操作…直到整个图遍历完成。

我们可以举个栗子:

对于这个图,从顶点1开始DFS,首先遍历1,接着有多路分支可选择,此时按照字典顺序,因此先遍历2,依旧有多路分支,遍历3,此时只有5可走,遍历5…6注意,到了6之后无路可走了,所以开始进行回退,首先回退到5,接着到3,在接下来到2,当回到2时,发现4还没有遍历过,遍历4,又无路可走了,回退到2,回退到1,遍历图完成,DFS结束。

输入

图的顶点个数n

接下来n行,每行都有:对第i个顶点vi,有mi条边,表示从vi到vj存在边

输出

按照字典顺序输出每个顶点的id、第一次被遍历的顺序(第几个被深搜搜到)和第二次被遍历的顺序(第几个被回退,注意这里需要再加上前面深搜的最大深度)

思路

简单的dfs,本题目最关键的核心:

1.用一个适当的数据结构存储顶点之间的关系

2.用一个标记数组标记已经被访问过的顶点

考虑输入的规模为n很小,采用邻接矩阵建图即可

邻接矩阵:如果一个图有n个顶点,那么我们就可以建立一个n*n的邻接矩阵,矩阵第i行第j列的值只能0或1,为0表示vi与vj没有边,反之则有边

复杂度分析

时间复杂度:建图O(n) + dfs其最坏情况为整个图的最大深度为顶点数n

总的时间复杂度为O(2n)

空间复杂度: 由于我们采取邻接矩阵存储图,空间复杂度为点的个数的平方,即O(n^2)

AC参考代码

#include <iostream>
#include <cstring>
#include <algorithm>
#include <queue>
#include <vector>
#define N 1001
using namespace std;
typedef struct Graph {
	int vexnums;
	int edgenums;
	int** edge;
};
int d[N], f[N],cnt = 1;
vector<int> visited;
void dfs(Graph& G, int start) {
	visited[start] = 1;
	d[start] = cnt;
	cnt++;
	for (int i = 0; i < G.vexnums; i++) {
		if (!visited[i] && G.edge[start][i]) {
			dfs(G, i);
		}
	}
	f[start] = cnt;
	cnt++;
}
int main()
{
	Graph G;
	cin >> G.vexnums;
	G.edge = new int*[G.vexnums];
	for (int i = 0; i < G.vexnums; i++) {
		G.edge[i] = new int[G.vexnums];
	}
	for (int x = 0; x < G.vexnums; x++) {
		for (int y = 0; y < G.vexnums; y++) {
			G.edge[x][y] = 0;
		}
	}
	int vi, vj, n;
	for (int i = 0; i < G.vexnums; i++) {
		cin >> vi >> n;
		for (int x = 0; x < n; x++) {
			cin >> vj;
			G.edge[vi - 1][vj - 1] = 1;
		}
	}
	visited.assign(G.vexnums, 0);
	for (int i = 0; i < G.vexnums; i++) {
		if (!visited[i]) {
			dfs(G, i);
		}
	}
	for (int i = 0; i < G.vexnums; i++) {
		cout << i + 1 << ' ' << d[i] << ' ' << f[i] << endl;
	}
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值