Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/jquery-ui/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Graph 如何使用递归深度优先搜索算法判断所有顶点之间是否存在路径?_Graph_Depth First Search - Fatal编程技术网

Graph 如何使用递归深度优先搜索算法判断所有顶点之间是否存在路径?

Graph 如何使用递归深度优先搜索算法判断所有顶点之间是否存在路径?,graph,depth-first-search,Graph,Depth First Search,我试图判断一个图是否是强连通的。要限定为强连通,图形应具有以下属性: 1) DFS算法将声明所有节点都可以从起始顶点到达 2) 当所有边的方向都反转(转置图)时,所有节点都可以从起始顶点到达 以下是我的DFS实现: public void dfs(String startName) { Vertex v = getVertex(startName); v.dist = 0; dfsVertex(v); } List<Vertex

我试图判断一个图是否是强连通的。要限定为强连通,图形应具有以下属性: 1) DFS算法将声明所有节点都可以从起始顶点到达 2) 当所有边的方向都反转(转置图)时,所有节点都可以从起始顶点到达

以下是我的DFS实现:

 public void dfs(String startName) {
        Vertex v = getVertex(startName);
        v.dist = 0;
        dfsVertex(v);
    }

 List<Vertex> wasVisited;
 List<Edge> wasVisitedEdge;

    private void dfsVertex(Vertex v) {

        wasVisited.add(v);

        for(Edge e: v.adj){

            if(!wasVisitedEdge.contains(e)){

                Vertex w = e.dest;

                if(!wasVisited.contains(w)){

                    wasVisitedEdge.add(e);
                    w.prev = v;
                    wasVisited.add(w);
                    w.dist = v.dist + 1;
                    dfsVertex(w);
                }
            }



        }

    }
public void dfs(字符串startName){
顶点v=获取顶点(startName);
v、 dist=0;
(v);
}
访问名单;
列表为VisitedEdge;
私有顶点(顶点v){
添加(v);
用于(边缘e:v.adj){
如果(!wasVisitedEdge.contains(e)){
顶点w=e.dest;
如果(!wasviest.contains(w)){
wasVisitedEdge。添加(e);
w、 prev=v;
添加(w);
w、 dist=v.dist+1;
顶点(w);
}
}
}
}
如何使用上述算法判断每个顶点之间是否存在路径


谢谢你的提示。

所以你的目标是检查图形是否强连接。这很有帮助,因为这样你就可以简单地假设你有一个任意的节点。您的算法所做的是通过连接边获取与查询节点相邻的每个节点

for(Edge e: v.adj)
检查是否已对其进行了搜索

if(!wasVisitedEdge.contains(e)) AND if(!wasVisited.contains(w))
wasVisitedEdge.add(e); AND wasVisited.add(w);
如果尚未搜索,则将其添加到列表中

if(!wasVisitedEdge.contains(e)) AND if(!wasVisited.contains(w))
wasVisitedEdge.add(e); AND wasVisited.add(w);
标记有关如何到达新看到的节点的信息

w.prev = v; AND w.dist = v.dist + 1;
然后使用这些相邻节点搜索“新”节点

但是,您的算法中有一个bug。请注意,您致电:

wasVisited.add()
两次。一次表示“v”,一次表示“w”。这样做的问题是,“w”成为下一个查询的“v”,因此在第一次调用原始根(或起始)节点后,您将保留列表中每个其他节点的副本

wasVisited
简单的解决方法是完全移除线路

wasVisited.add(w);
然后代码就会正常工作。在代码执行之后

wasVisited
将包含可以从原始查询的根节点访问的每个节点。从这里,您可以简单地检查图中的每个节点是否存储在列表中。如果对每个节点进行了说明,则列表是强连接的。否则它不是强连通的。无论图形是有向的还是无向的,该算法都应该有效