本文共 3259 字,大约阅读时间需要 10 分钟。
下面的内容是关于尝试使用CLRS上的DFS与拓扑排序检查有向图中是否存在环的实现。
在本次实现中,我们采用了基于深度优先搜索(DFS)和拓扑排序的方法来检测有向图中是否存在环。这种方法不仅能够高效地完成任务,还能很好地理解图的结构及其特性。
DFS是图遍历中最常用的算法之一,通过递归或栈结构来探索图中的所有节点。对于本次实现,我们采用了递归的方式来进行DFS搜索。
#include#include #include #include #include #include #include #include
void DFS_noncursion(vector> &node_next, vector &node_set) { stack
在DFS的实现中,我们使用了一个标记变量color来记录节点的访问状态:
0:未被访问1:正在访问中2:已访问完成通过递归DFS,我们可以实现对图中所有节点的遍历,并在访问过程中记录节点的访问时间和父节点信息。这种方法的时间复杂度为O(V + E),其中V是节点数,E是边数。
拓扑排序是一种基于有向图的排序方法,其核心思想是确定一个线性序列,使得图中每一条边都从左到右指向下一个节点。我们可以通过DFS来生成拓扑序列,然后再对拓扑序列进行排序。
通过这种方法,我们可以得到一个拓扑排序结果,并在此基础上检查图中是否存在环。
在实际应用中,我们可以通过以下步骤来检查有向图是否存在环:
bool canFinish(int numCourses, vector> prerequisites) { vector > node_next(numCourses, vector (0)); vector node_set; vector > node_next_T(numCourses, vector (0)); vector node_set_T; for (int i = 0; i < numCourses; ++i) { auto temp = new Node(i, 0, node_next[i], 0, 0, 0); auto temp_T = new Node(i, 0, node_next_T[i], 0, 0, 0); node_set.push_back(temp); node_set_T.push_back(temp_T); } for (int i = 0; i < prerequisites.size(); ++i) { node_next[prerequisites[i].first].push_back(node_set[prerequisites[i].second]); node_next_T[prerequisites[i].second].push_back(node_set_T[prerequisites[i].first]); } for (int i = 0; i < numCourses; ++i) { node_set[i]->next = node_next[i]; node_set_T[i]->next = node_next_T[i]; } static bool sign = 0; static int times = 0; bool canFinish = !DFS(node_next, node_set); return canFinish; }
int DFS(vector> &node_next, vector &node_set) { for (int i = 0; i < node_set.size(); ++i) { if (node_set[i]->color == 0) { if (DFS_VISIT(node_next, node_set, node_set[i]->val)) { return 1; } } } return 0;}
int DFS_VISIT(vector> &node_next, vector &node_set, int targets) { times++; int target = find_index(node_set, targets); node_set[target]->start_time = times; node_set[target]->color = 1; for (int i = 0; i < node_next[target].size(); ++i) { if (node_next[target][i]->color == 0) { node_next[target][i]->parent = node_set[target]->val; if (sign) return 1; DFS_VISIT(node_next, node_set, node_next[target][i]->val); } } times++; node_set[target]->end_time = times; return 0;}
通过上述方法,我们可以有效地检查有向图中是否存在环。这种方法的核心思想是利用DFS遍历图,并结合拓扑排序的概念来确定节点的访问顺序,从而快速发现图中的环。如果在实际应用中发现某个节点无法被访问,则说明该节点所在的子图中存在环。
这种方法不仅能够高效地完成任务,还能很好地理解图的结构及其特性,是解决实际问题的有效方法。
转载地址:http://frsm.baihongyu.com/