使用DFS检查无向图中的循环
Checking for a cycle in an undirected graph using DFS?
因此,我为DFS编写了以下代码:
void dfs (graph * mygraph, int foo, bool arr[]) // here, foo is the source vertex
{
if (arr[foo] == true)
return;
else
{
cout<<foo<<"t";
arr[foo] = true;
auto it = mygraph->edges[foo].begin();
while (it != mygraph->edges[foo].end())
{
int k = *it;
if (arr[k] == false)
{
//cout<<k<<"n";
dfs(mygraph,k,arr);
//cout<<k<<"t";
}
it++;
}
}
//cout<<"n";
}
现在,我读到在一个无向图中,如果当DFS时,它再次返回到同一个顶点,这是一个循环。因此,我所做的是,
bool checkcycle( graph * mygraph, int foo, bool arr[] )
{
bool result = false;
if (arr[foo] == true)
{
result = true;
}
else
{
arr[foo] = true;
auto it = mygraph->edges[foo].begin();
while (it != mygraph->edges[foo].end())
{
int k = *it;
result = checkcycle(mygraph,k,arr);
it++;
}
}
return result;
}
但是,我的checkcycle函数返回true,即使他们没有循环。为什么呢?我的功能有问题吗?没有执行问题,否则我就会调试,但他们似乎是我的逻辑有问题。
注意,您的函数并不完全像您想象的那样。让我试着一步一步地解释一下这里发生了什么。假设下列关系:(1,2),(1,3),(2,3)。我没有假设反射性(也就是说,(1,2)并不意味着(2,1))。关系是直接的。
- 从节点1开始。标记为已访问
- 迭代它的子元素(2和3)
- 在节点2时,递归调用
check cycle
。此时,2也被标记为已访问。 - 递归调用现在访问3(深度搜索)。3也被标记为访问
- 呼叫步骤4死亡返回
false
- 呼叫步骤3死亡返回
false
我们回到了第二步。现在我们将迭代节点3,它已经在步骤4中被标记。它只返回
true
。你需要一个访问节点的堆栈,或者你只搜索原始节点。堆栈也会检测子周期(不包括原始节点的周期),但它也会占用更多的内存。
编辑:节点堆栈不仅仅是一堆true
/false
值,而是一堆节点号。如果一个节点存在于堆栈中,则在当前堆栈跟踪中访问了该节点。
然而,有一个更内存友好的方法:设置arr[foo] = false;
作为调用死亡。像这样:
bool checkcycle( graph * mygraph, int foo, bool arr[], int previousFoo=-1 )
{
bool result = false;
if (arr[foo] == true)
{
result = true;
}
else
{
arr[foo] = true;
auto it = mygraph->edges[foo].begin();
while (it != mygraph->edges[foo].end())
{
int k = *it;
// This should prevent going back to the previous node
if (k != previousFoo) {
result = checkcycle(mygraph,k,arr, foo);
}
it++;
}
// Add this
arr[foo] = false;
}
return result;
}
我想应该够了。
编辑:现在应该支持无向图。节点:此代码未被测试编辑:更详细的解决方案请参见强连接组件
编辑:虽然在评论中给出了具体的解决方案,但这个答案是市场所接受的。
在checkcycle开始之前,arr[]中的所有bool都设置为false吗?
你确定你的节点迭代器没有在它已经遍历的边缘上翻倍(因此无论周期如何,都会多次看到起始节点)?
相关文章:
- 如何循环打印顶点结构
- 如何在C++中从两个单独的for循环中添加两个数组
- C++我的数学有什么问题,为什么我的代码不能正确循环
- 正在尝试了解输入验证循环
- std::map<struct,struct>::find 找不到匹配项,但是如果我循环通过 begin() 到 end(),我在那里看到匹配项
- 循环后如何继续阅读
- Ardunio UNO解决了多个重叠的定时器循环
- Eigen如何在容器循环中干净地附加矩阵
- 在某些循环内使用vector.push_back时出现分段错误
- 我正在使用嵌套的while循环来解析具有多行的文本文件,但由于某种原因,它只通过第一行,我不知道为什么
- 为什么我的for循环不能正确获取argv
- 如何声明特征矩阵,然后通过嵌套循环初始化它
- while循环中while循环的时间复杂度是多少
- C++中的高效循环缓冲区,它将被传递给C样式数组函数参数
- 为什么在这个代码结束循环中没有得到结束
- 在基于范围的for循环中使用结构化绑定声明
- 为什么我在图中的DFS循环检测总是返回true
- 用DFS检测有向图中的循环
- 使用DFS检查无向图中的循环
- c++图形DFS循环检查