寻找 有向图/无向图 所有环路的DFS暴力求解法(ps:C++代码,复杂度爆炸警告,生产环境慎用)

思路:

1、DFS算法可以求解图中从一点到另一点的全部路径。

2、通过枚举所有顶点V_i的邻接点v_i,然后通过DFS寻找枚举点v_iV_i的所有路径来寻找环路。

3、思路很简单,但是算法复杂度确实是太高了。

下面上代码:

#include <iostream>
#include <vector>
#include <algorithm>

using namespace std;

const int M = 100;
int n, e, G[M][M];
bool vis[M];

//初始化图
void initGraph() { 
	cin >> n >> e;
	int ti, tj;
	for (int i = 0; i < e; i++) {
		cin >> ti >> tj;
		G[ti][tj] = 1;
	}
}


vector<vector<int>> finalResult; //存储最终的所有找到的环
vector<int> path;	//dfs路径栈

//判断两个无序的vector内元素是否完全一样
bool isSame(vector<int> v1,vector<int> v2) {
	if (v1.size() != v2.size()) {
		return false;
	} else {
		sort(v1.begin(),v1.end());
		sort(v2.begin(),v2.end());
		return v1==v2;
	}
}
//判断t在finalResult是否已经存在
bool isExist(vector<int> &t) {
	for (int i = 0; i < finalResult.size(); i++) {
		if (isSame(finalResult[i], t)) {
			return true;
		}
	}
	return false;
}
//打印路径
void printPath(int &begin) {
	cout << begin << " ";
	for (int i = 0; i < path.size(); i++) {
		cout << path[i] << " ";
	}
	cout << endl;
}
//dfs寻找起点s到终点d的全部路径
void dfs(int s, int d,int &begin) {
	if (s==d) {
		path.push_back(s);
		if (path.size() > 2 && !isExist(path)) {
			printPath(begin);
			finalResult.push_back(path);
		}
		path.pop_back();
		vis[s] = false;
		return;
	}
	vis[s] = true;
	path.push_back(s);
	for (int i = 0; i < n; i++) {
		if (!vis[i] && G[s][i]==1) {
			dfs(i,d,begin);
		}
	}
	vis[s] = false;
	path.pop_back();
}
//调用dfs函数寻找该图的所有环路
void findAllCircle() {
	for (int i = 0; i < n; i++) {
		for (int j = 0; j < n; j++) {
			if (G[i][j]==1) {
				dfs(j, i, i);
				fill(vis, vis + n, false);
				path.clear();
			}
		}
	}
}
int main() {
	initGraph();
	findAllCircle();
	return 0;
}

---测试用例---

格式:

顶点数n [空格] 边数e
边1的出点 [空格] 边1的入点
边2的出点 [空格] 边2的入点
边3的出点 [空格] 边3的入点
...
边e的出点 [空格] 边e的入点

输入:(有向图)

6 7
0 1
0 2
2 3
2 4
3 4
4 0
1 5

输出:

无向图修改一下建图代码即可。

  • 2
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
以下是一个用matlab实现深度优先搜索(DFS)来寻找有向图环路的示例代码: ```matlab function hasCycle = dfs(graph) % graph表示有向图的邻接矩阵,hasCycle表示有向图中是否存在环路 n = size(graph, 1); % 有向图顶点数 visited = zeros(n, 1); % 标记每个顶点是否已访问过 onStack = zeros(n, 1); % 标记每个顶点是否在递归调用栈上 hasCycle = false; % 初始默认没有环路 for v = 1:n % 从每个顶点开始深度优先搜索 if ~visited(v) hasCycle = dfsVisit(graph, visited, onStack, v); if hasCycle % 如果存在环路则直接返回 return; end end end end function hasCycle = dfsVisit(graph, visited, onStack, v) % 在有向图中从顶点v开始深度优先搜索,visited和onStack记录访问状态,hasCycle表示是否存在环路 visited(v) = true; % 标记当前顶点已访问 onStack(v) = true; % 标记当前顶点在递归调用栈上 for w = find(graph(v,:)) % 遍历v的所有邻居节点w if ~visited(w) hasCycle = dfsVisit(graph, visited, onStack, w); if hasCycle % 如果存在环路则直接返回 return; end elseif onStack(w) % 如果w已经在递归调用栈上,则存在环路 hasCycle = true; return; end end onStack(v) = false; % 当前顶点的所有邻居节点已经访问完毕,将其从递归调用栈上移除 hasCycle = false; % 当前顶点的所有邻居节点均已访问过,不存在环路 end ``` 该代码中,dfs函数是主函数,dfsVisit函数是递归函数。在dfs函数中,我们从每个顶点开始深度优先搜索,如果存在环路则直接返回;在dfsVisit函数中,我们从顶点v开始访问其所有邻居节点w,如果w已经在递归调用栈上,则存在环路,否则继续访问w的邻居节点。在访问完v的所有邻居节点后,将其从递归调用栈上移除,返回当前顶点的访问状态。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

_Kirito

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值