当前位置: 首页 > 知识库问答 >
问题:

如何在有向图的选定节点内找到循环?(C++)

吴城
2023-03-14

我目前正在研究一个在有向图中寻找由选定节点组成的圈的问题。

对于这里描述的实例:

在节点1,2,3内有一个循环,在1,2,4内没有发现循环。我已经尝试用下面的操作来实现算法:

    null
bool hasLoop(const int startNode, const bool directions[][MAX_DOT_NUM], const int nodesLen, bool nodesVisited[], const int selectedNodes[], const int selectedNum){
nodesVisited[startNode] = true;

for(int i = 0; i < nodesLen; i++){ //loop through all nodes 
    if(withinSelected(i, selectedNodes, selectedNum) == false) continue;  //check loop only for selected nodes
    if(directions[startNode][i] == 1){ //connected and is within selected nodes
        if(nodesVisited[i] == true){ 
            return true;                
        }else{
            if(hasLoop(i, directions, nodesLen, nodesVisited, selectedNodes, selectedNum)){
                return true;
            }
        }
    }
}
return false;

但是,这个实现并不适用来自我正在使用的在线判断的所有测试数据。我发现我的算法不同于深度优先搜索,深度优先搜索使用白、灰、黑数组来存储未访问、正在访问或不需要访问的节点,我想知道这是否是导致问题的原因。

希望在您的帮助下,我能找到导致此实现不适用于所有情况的bug!非常感谢你阅读这篇文章!

编辑:这是一个有向图!对此很抱歉。

bool hasLoop(const int currentNode, const bool directions[][MAX_DOT_NUM], const int nodesLen, bool nodesVisited[], const int selectedNodes[], const int selectedNum, const int startNode){
// cout << currentNode << " -> ";
nodesVisited[currentNode] = true;

for(int i = 0; i < nodesLen; i++){
    if(withinSelected(i, selectedNodes, selectedNum) == false) continue;
    if(directions[currentNode][i] == 1){ //connected and is within selected nodes
        if(nodesVisited[i] == true){ 
            if(i == startNode) return true;        
        }else{
            if(hasLoop(i, directions, nodesLen, nodesVisited, selectedNodes, selectedNum, startNode)){
                return true;
            }
        }
    }
}
return false;

共有1个答案

洪浩
2023-03-14

您的实现是一个DFS,但对于不创建循环的“侧节点”将失败:

考虑有3个节点的图(A,B,C):

      A
    /   \
   /     \
  V       V
  B <---- C

你的算法会告诉图有一个循环,而事实上-它没有!

在这两种解决方案中,只在包含“选定节点”的子图上应用算法。这两种解决方案都是O(V+E)时间和O(V)空间。

 类似资料:
  • 我正在考虑以下问题(非常粗略的描述): 假设我们有一个图,其中边被分配了一些非负成本,一个起始节点和一些成本常数。找出: 一组节点,可从到达,其中从起始节点到中任何节点的最短路径成本不大于 对于集合中的每个,上面是最短路径的成本 基本上是有成本限制的Dijkstra。 我的主要问题是:图论中关于这个问题的正确术语是什么? 我一直在看“可访问性”或“可达性”,但这些似乎是错误的关键词。 最终,我正在

  • 这是我的算法。 我做了一个。每次当我找到时,我都知道我得到了一个有向循环。 然后我将暂时沿着向后(直到我在循环中遍历所有顶点),并计算。 我的算法正确吗? 如果我的算法正确,时间复杂度是多少? 这个问题有没有更好的算法?

  • 给定:有权边的有向无环图,其中一个节点可以有多个父节点。 问题:对于根节点的每个子节点,找到一条从该子节点到某个叶的最小代价(权重之和)路径。一个节点只能存在于一个这样的最小开销路径中。 图表示例: > 这个逻辑有道理吗?我担心这种消除冲突的迭代方式可能对某些图不收敛。例如,在重新计算节点2的最小路径时,如果现在发现2->5是最小路径,并且假设在第一次迭代期间,节点5在其他节点的最小路径中使用,那

  • 问题内容: 在查找循环方面已经存在一些问题,但是我没有找到SQL的解决方案(首选MSSQL)。 这些表将是Node(NodeID INT)和Edge(EdgeID INT,NodeID1 INT,NodeID2 INT) 在有向图中找到周期的性能很好的解决方案是什么? 问题答案: 该解决方案非常简单明了,但时间更长: 首先,将生成通过该图的所有路径的列表,以使任何路径都不会包含同一条边。 从此信息

  • 问题内容: 我有一个非循环有向图。我想为每个顶点分配级别,以确保如果边(v1,v2)在图中,则level(v1)> level(v2)。每当(v1,v2)和(v3,v2)在图中时,如果level(v1)= level(v3),我也希望它。同样,可能的级别是离散的(也可以将它们作为自然数)。理想的情况是,每当(v1,v2)在图中并且没有从v1到v2的其他路径时,level(v1)= level(v2

  • 我试图找到图G中最负循环的路径,它从指定的源节点S开始和结束。 我研究了Bellman-Ford算法(以下称为“Huang算法”)的应用/扩展,该算法描述了如何找到从指定节点可到达的负循环。然而,这并不能确保从S开始的“全周期”- 以下是我目前对此主题的研究: 在Bellman-Ford算法的第n次迭代中,如果一条边可以松弛,则该图包含一个负循环。使用Huang算法,我可以通过前置字典追溯负循环的