删除一些边缘后的 DFS

Posted

技术标签:

【中文标题】删除一些边缘后的 DFS【英文标题】:DFS after remove some edge 【发布时间】:2016-02-08 15:38:59 【问题描述】:

我有一个图,其中包含一个源顶点和一个边列表,在每次迭代中,列表中的一条边将从图中删除。

对于每个顶点,我必须打印它失去与源顶点的连接后的迭代次数——顶点和源之间将没有路径。

我的想法是在每次迭代中从源顶点运行 DFS 算法,并增加与源顶点有连接的顶点的值——在顶点和源顶点之间有一条路径。

我确信有比在每次迭代中从源顶点运行 dfs 算法更好的主意。但我不知道如何以更好、更快的方式解决问题。

【问题讨论】:

那么,您的实际问题是“我可以使用什么其他更有效的算法来解决问题”? 重要的细节是,你知道哪个边缘,哪个顶点之间被删除了吗?如果不是,你必须搜索才能找到它,所以我怀疑有什么比你描述的更好......如果是,那么我认为有潜力。 是的,我确切地知道删除了哪条边。我有要删除的边缘列表并从列表的第一个位置开始删除 【参考方案1】:

由于您事先拥有整个边列表,因此您可以对其进行反向处理,连接图形而不是断开连接。

在伪代码中:

GIVEN:
edges = list of edges
outputMap = new empty map from vertex to iteration number
S = source vertex

//first remove all the edges in the list
for (int i=0;i<edges.size();i++) 
   removeEdge(edges[i]);


//find vertices that are never disconnected
//use DFS or BFS
foreach vertex reachable from S

   outputMap[vertex] = -1;


//walk through the edges backward, reconnecting
//the graph
for (int i=edges.size()-1; i>=0; i--)

    Vertex v1 = edges[i].v1;
    Vertex v2 = edges[i].v2;
    Vertex newlyConnected = null;

    //this is for an undirected graph
    //for a directed graph, you only test one way
    //is a new vertex being connected to the source?
    if (outputMap.containsKey(v1) && !outputMap.containsKey(v2))
        newlyConnected = v2;
    else if (outputMap.containsKey(v2) && !outputMap.containsKey(v1))
        newlyConnected = v1;

    if (newlyConnected != null)
    
        //BFS or DFS again
        foreach vertex reachable from newlyConnected
        
            //It's easy to calculate the desired remove iteration number
            //from our add iteration number
            outputMap[vertex] = edges.size()-i;
        
    
    addEdge(v1,v2);


//generate output
foreach entry in outputMap

    if (entry.value >=0)
    
       print("vertex "+entry.key+" disconnects in iteration "+entry.value);
    

该算法实现了线性时间,因为每个顶点在连接到源之前只涉及单个 BFS 或 DFS。

【讨论】:

【参考方案2】:

它有助于逆转时间,因此我们正在考虑逐条添加边并确定何时实现与源的连接。您在每一步之后执行遍历的想法是一个很好的想法。要将总成本降低到线性,您需要进行以下优化和摊销分析。优化是您保存从遍历到遍历的一组已访问顶点,并将该集合视为一个“超顶点”,在遍历时删除集合内的边。每次遍历的成本与删除的边数成正比,因此是摊销的线性运行时间。

【讨论】:

以上是关于删除一些边缘后的 DFS的主要内容,如果未能解决你的问题,请参考以下文章

前端算法-岛屿的最大面积 DFS(深度优先搜索) 质数计数

LC 6223.移除子树后的二叉树高度(dp ||dfs序)

如何删除 dfs 表中的重复数据?

LeetCode 695. 岛屿的最大面积 (DFS)

找到顶点边缘(多边形)的最佳算法

Android Studio 上传GitHub项目失败后的一些问题