C++ 使用DFS检测有向图中的循环?
所以,我试图在有向图中找到一个使用DFS的循环。现在,我知道如果一个图的拓扑排序是不可能的,那么这个图包含一个圈。我为拓扑排序做了以下算法。我不确定应该在哪里修改这段代码以返回true或false,并检查我的图形是否包含循环。以下是我使用的算法:C++ 使用DFS检测有向图中的循环?,c++,algorithm,graph,depth-first-search,C++,Algorithm,Graph,Depth First Search,所以,我试图在有向图中找到一个使用DFS的循环。现在,我知道如果一个图的拓扑排序是不可能的,那么这个图包含一个圈。我为拓扑排序做了以下算法。我不确定应该在哪里修改这段代码以返回true或false,并检查我的图形是否包含循环。以下是我使用的算法: DFS-Loop (Graph G) 1. Mark all vertices as unexplored. 2. Set label = n // number of vertices 3. For each vertex V (belonging
DFS-Loop (Graph G)
1. Mark all vertices as unexplored.
2. Set label = n // number of vertices
3. For each vertex V (belonging to) G
-- If V not yet explored,
-- DFS (G,V)
4. Set f(V) = current_label // here, f(V) is basically the position of V in the ordering
5. current_label--
Where DFS(G,V) will be something like:
1. Mark V as explored.
2. For every vertex K belonging to Adj.(V)
-- If K is not explored,
-- Call DFS(G,K)
对于是否包含循环,我应该在何处添加此检查
谢谢 在有向图中寻找圈的最简单方法如下 使用顶点的三种状态:未探索、正在探索和完全探索。输入新顶点时,将其设置为“正在探索”,使用完顶点后,将其设置为“完全探索”。现在,当你迭代某个顶点的邻域时,如果你到达一个正在探索的顶点,那么有一个循环
DFS(G,V):
1. Mark V as "being explored"
2. For every vertex K belonging to Adj.(V)
-- If K is not explored,
-- Call DFS(G,K)
-- else if K is "being explored" (not "fully explored")
-- then there is a cycle
3. Mark V as "fully explored"
通过从找到的正在探索的顶点回溯,可以找到循环
另一种方法是只允许基于DFS的拓扑排序运行并创建一些顶点排序。现在迭代所有边并检查它们是否正确定向。如果所有边都正确定向,那么如果没有圈,则至少有一个圈。在有向图中查找圈的最简单方法如下所示 使用顶点的三种状态:未探索、正在探索和完全探索。输入新顶点时,将其设置为“正在探索”,使用完顶点后,将其设置为“完全探索”。现在,当你迭代某个顶点的邻域时,如果你到达一个正在探索的顶点,那么有一个循环
DFS(G,V):
1. Mark V as "being explored"
2. For every vertex K belonging to Adj.(V)
-- If K is not explored,
-- Call DFS(G,K)
-- else if K is "being explored" (not "fully explored")
-- then there is a cycle
3. Mark V as "fully explored"
通过从找到的正在探索的顶点回溯,可以找到循环
另一种方法是只允许基于DFS的拓扑排序运行并创建一些顶点排序。现在迭代所有边并检查它们是否正确定向。如果所有边都正确定向,则没有循环,否则至少有一个循环。我建议阅读《算法-介绍Cormen等人》中的相应章节 基本上,当您重新访问未完成的顶点时,需要检测: 不将顶点V标记为已探测/未探测,而是添加当前已探测的附加标签状态。 每个顶点在开始时都标记为未探测,与在瞬间一样。但它在DFS的步骤1中标记为“当前已探索”,而不是在DFS的for循环2之后标记为“已探索” 在DFS中递归调用之前,请检查状态。如果它未被探测,只需像当前一样递归调用。如果当前正在探索,则表示您已检测到一个循环!据探索,这被称为前沿,在此不再感兴趣 注意,这可以集成到拓扑排序算法中
我建议在Cormen网站上也能找到这一点。我建议阅读《算法-Cormen等人简介》中的相应章节 基本上,当您重新访问未完成的顶点时,需要检测: 不将顶点V标记为已探测/未探测,而是添加当前已探测的附加标签状态。 每个顶点在开始时都标记为未探测,与在瞬间一样。但它在DFS的步骤1中标记为“当前已探索”,而不是在DFS的for循环2之后标记为“已探索” 在DFS中递归调用之前,请检查状态。如果它未被探测,只需像当前一样递归调用。如果当前正在探索,则表示您已检测到一个循环!据探索,这被称为前沿,在此不再感兴趣 注意,这可以集成到拓扑排序算法中
我建议您也在Cormen中查找此图。对于无向图,只需遵循以下步骤- 1而不是布尔数组,使其为int类型,所有索引初始化为-1 这里-1=未探索,0=正在探索,1=完全探索 2将全局布尔变量标志初始化为false 此处true=包含循环,false=不包含循环
3现在写DFS如下:C++代码-< /P>
void dfs(int s)
{
visited[s] = 0;
for(int i = 0; i < adj[s].size(); i++)
{
if(visited[ adj[s][i] ] == -1)
{
dfs(adj[s][i]);
}
else if(visited[adj[s][i]] == 1)
{
flag = true;
return;
}
}
visited[s] = 1;
}
对于无向图,只需执行以下步骤- 1而不是布尔数组,使其为int类型,所有索引初始化为-1 这里-1=未探索,0=正在探索,1=完全探索 2将全局布尔变量标志初始化为false 此处true=包含循环,false=不包含循环
3现在写DFS如下:C++代码-< /P>
void dfs(int s)
{
visited[s] = 0;
for(int i = 0; i < adj[s].size(); i++)
{
if(visited[ adj[s][i] ] == -1)
{
dfs(adj[s][i]);
}
else if(visited[adj[s][i]] == 1)
{
flag = true;
return;
}
}
visited[s] = 1;
}
visited[adj[s][i]]==1不正确。应访问[adj[s][i]==0,即当顶点正在移动时explored@suraznegi我写的算法是针对无向图的,在这种情况下,visited[adj[s][I]]==1是正确的。visited[adj[s][I]==1是不正确的,它应该访问[adj[s][I]==0,即当顶点
正在explored@suraznegi我写的算法是针对无向图的,在这种情况下,访问[adj[s][I]]==1是正确的。如果充分研究K,则应该是正确的。如果我使用2节点1边图,您的算法将失败。它会将其标记为有一个循环。@ManishSharma,请注意,如果完全探索了K,则该图为directedIt,应为else。如果我使用2节点1边图,您的算法将失败。它会将其标记为有一个循环。@ManishSharma,请注意,该图是有方向的