我有一个带有一个源顶点和一个边列表的图,在每次迭代中,列表中的一条边将从图中删除。
对于每个顶点,我必须在它失去与源顶点的连接后打印迭代次数——顶点和源之间将没有路径。
我的想法是在每次迭代中从源顶点运行 DFS 算法并增加与源顶点有连接的顶点的值——在顶点和源顶点之间有一条路径。
我确信有比在每次迭代中从源顶点运行 dfs 算法更好的主意。但我不知道如何以更好、更快的方式解决问题。
我有一个带有一个源顶点和一个边列表的图,在每次迭代中,列表中的一条边将从图中删除。
对于每个顶点,我必须在它失去与源顶点的连接后打印迭代次数——顶点和源之间将没有路径。
我的想法是在每次迭代中从源顶点运行 DFS 算法并增加与源顶点有连接的顶点的值——在顶点和源顶点之间有一条路径。
我确信有比在每次迭代中从源顶点运行 dfs 算法更好的主意。但我不知道如何以更好、更快的方式解决问题。
由于您事先拥有整个边列表,因此您可以向后处理它,连接图形而不是断开连接。
在伪代码中:
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。
它有助于逆转时间,因此我们正在考虑逐个添加边并确定何时实现与源的连接。您在每一步之后执行遍历的想法是一个很好的想法。要将总成本降低到线性,您需要进行以下优化和摊销分析。优化是您保存从遍历到遍历的一组已访问顶点,并将该集合视为一个“超顶点”,在遍历时删除集合内的边。每次遍历的成本与因此删除的边数成正比,因此是摊销的线性运行时间。