我想迭代包含~10 7 顶点的无向图的每个连通分量。即我想在每个向量上调用一些函数f(V i )V 1 ... V k 其中V i < / sub>是一个向量,包含附加到图的第i个连通分量中每个节点的数据。
执行此操作的最快算法是什么?
我的第一个想法是:
答案 0 :(得分:1)
运行经典connected components algorithm。通常,这会操纵disjoint-sets data structure。
创建一个哈希表,将节点映射到链接的节点列表。
迭代每个节点
一个。在disjoint-sets数据结构中找到代表节点
湾如有必要,为哈希表中的代表节点创建链接列表
℃。将节点添加到与代表节点
这需要有效的线性时间(即Θ(| E | + | V |),预期(在广泛接受的理解下,不相交集合实际上是线性时间)。
您现在有一个哈希表,其条目数是连接组件的数量。每个值都是连接组件中所有节点的链接列表。您现在可以线性迭代所需的任何内容。
答案 1 :(得分:0)
是的DFS是一个很好的选择。但请记住,如果运行递归DFS,对于给定范围10 ^ 7个节点,您可能会遇到内存问题。因为在worts案例中所有节点都会形成一个链,你需要大量的堆栈,导致STACKOVERFLOW(:D)
尝试做:
BFS通常用于最短路径问题,但它可以用于许多其他应用程序,例如这个。这将从堆中获取队列数据结构的空间,其中通常的递归DFS从堆栈中占用空间。
答案 2 :(得分:0)
如果将图形存储为邻接列表,并且顶点由1
到n-1
的整数表示,则不需要union-find或hash表。
假设g[v]
是与v
相邻的顶点列表(向量)。此外,让cc
为列表列表(向量矢量),其中cc[i]
表示i-th
连通分量中的顶点。出于实现目的,当且仅当我们在visited[v] = true
例程中检查v
时,我们才会使用DFS
。然后伪代码看起来像那样:
dfs(v, current_cc):
visited[v] = true
current_cc.append(v)
for u in g[v]:
if not visited[u]:
dfs(u, current_cc)
for v = 0 to n-1:
visited[i] = false
for v = 0 to n-1:
if not visited[v]:
current_cc = []
dfs(v, current_cc)
cc.append(current_cc)
//From now, cc[i] is a list of vertices in the i-th connected component,
//so we can easily iterate and call whatever we want on them.