BFS检测不应该出现的循环

BFS detecting cycles where it should not be

本文关键字:循环 检测 不应该 BFS      更新时间:2023-10-16

我已经实现了一个BFS算法来检测图中的循环,这是以下代码:

            void hasCycle(node *root,string start){  
            if(root->visted){
                if(root->name == start) cout << "Has cycle" << endl;
                else return;
            }
            root->visted = true;
            int ind;
            for(ind = 0; ind < root->adj.size(); ind++)
                hasCycle(root->adj[ind], start);
            root->visted = false;
            }

其中,start是起始节点。其中node是以下结构:

            struct node{
                string name;
                bool   visted;
                vector <node *> adj;
            };

这是我构建的图:

            Graph *grp = new Graph();
            grp->addVertex("A");
            grp->addVertex("B");
            grp->addVertex("C");
            grp->addEdge("A","B");
            grp->addEdge("B","A");
            grp->addEdge("A","C");
            grp->addEdge("C","A");

输出为:有周期有周期具有周期

正确的输出是零,因为没有循环。我花了很多时间试图调试这个,请帮忙!

注意:这不是一个有向图,所以我希望它们是双边

我想您希望在无向图中有一个大小为3或更大的循环。在这种情况下,在检查"visited"时,应该忽略BFS遍历中的父级。

此处的一些问题:

  1. BFS不适合在图中寻找循环。例如,查看无向图A->B->C->A,来自A的BFS将首先发现A,然后发现BC,并将在那里停止-而不检测循环
  2. 您的实现不应该两次使用无向边,而且您的实现确实使用了,对于每个uv,它同时使用u->vv->u(*)
  3. 您的实现只检测到通过start的循环,它将错过"laso"循环[可以从start访问但不包含start]

一个可能的解决方案:请注意,对于非有向图,对于大小为|V|的每个连通分量,如果有超过|V|-1的边,则该分量不是树,并且该图在列表中有一个循环[因为有向图中的树是没有循环的最大结构]。
因此,为了找到是否存在循环,你可以找到所有连接的组件[BFS对它有好处],并检查每个这样的组件是否包含超过|V|-1的边。

(*)2实际上是有争议的,但在标准的BFS实现中,这样做没有意义,因为BFS是用来发现节点的,如果你已经使用了一条边,那么连接到它的两个顶点都已经被发现了。