Algorithm 从邻接列表计算每个顶点的可达性
给定DAG的邻接列表Algorithm 从邻接列表计算每个顶点的可达性,algorithm,graph-theory,graph-algorithm,floyd-warshall,transitive-closure,Algorithm,Graph Theory,Graph Algorithm,Floyd Warshall,Transitive Closure,给定DAG的邻接列表Map,我想计算每个顶点的可达性(即,如果存在从u到v的路径) 静态映射可达性(Map adjList){} 我知道在O(V^3) //将邻接列表转换为邻接矩阵矩阵 无效可达性(布尔mat[][]){ 最终int N=材料长度; 对于(int k=0;k
Map
,我想计算每个顶点的可达性(即,如果存在从u到v的路径)
静态映射可达性(Map adjList){}
我知道在O(V^3)
//将邻接列表转换为邻接矩阵矩阵
无效可达性(布尔mat[][]){
最终int N=材料长度;
对于(int k=0;k
但是我有一个稀疏图(和一个邻接列表),那么最快的方法是什么呢?一个O(V*(V+E))
解决方案可以是从图中的每个节点执行一个简单的操作,并计算其可达性集。假设java中的| E | 2^V//Map
i=n-1
而(i>=0):
设v为v[i]中的顶点
已连接[v]。添加(v)
对于每个边(v,u):
//因为图是DAG,我们按相反的顺序处理
//已连接[u]的值已知,因此我们可以使用它。
已连接[v]。添加所有(已连接[u])
这里是一个简单的Scala中的O(|V | | E |)
解决方案(基本上,对于每个顶点,执行DFS):
这里的可执行版本:您能再解释一下这行
connected(v)=union{connected(u)| for all edge(v,u)}u{v}
吗?谢谢@对于每个节点u
,您都有一组其他节点连接到它,并用连接(u)
表示。将所有传出边缘从v
中取出,并合并连接到它们的节点,然后在末尾添加v
。这将为您提供一组连接到v
的已连接节点。但是,我不需要递归地进行联合吗??你能用一些伪代码更新答案吗…@wrick你熟悉动态编程吗?是的,但我不明白-什么是关联的。它最初是一张空地图吗?
// Convert adjList to adjacency matrix mat
void reachability(boolean mat[][]) {
final int N = mat.length;
for (int k = 0; k < N; k++)
for (int i = 0; i < N; i++)
for (int j = 0; j < N; j++)
mat[i][j] |= mat[i][k] && mat[k][j];
}
V = [v0,v1,...,vn-1]
V = topological_sort(V) //O(V+E)
connect = new Map:V->2^V //Map<Vertex,Set<Vertex>> in java
i = n-1
while (i >= 0):
let v be the vertex in V[i]
connected[v].add(v)
for each edge (v,u):
//since the graph is DAG, and we process in reverse order
//the value of connected[u] is already known, so we can use it.
connected[v].addAll(connected[u])
type AdjList[A] = Map[A, Set[A]]
def transitiveClosure[A](adjList: AdjList[A]): AdjList[A] = {
def dfs(seen: Set[A])(u: A): Set[A] = {
require(!seen(u), s"Cycle detected with $u in it")
(adjList(u) filterNot seen flatMap dfs(seen + u)) + u
}
adjList.keys map {u =>
u -> dfs(Set.empty)(u)
} toMap
}