给定一个节点数组和一个边数组,如何计算连通图的数量?
答案 0 :(得分:1)
答案 1 :(得分:1)
您可以使用联合查找(您可以搜索它)。从所有节点开始作为单独的集合,然后为每个边缘连接边缘连接到同一集合的两个节点。然后通过遍历所有节点并查找有多少不同的代表来检查有多少不同的集合。
答案 2 :(得分:1)
详细说明quasiverse的答案,这里有一个简短的伪代码:
make_set(v)创建一个新集合,其唯一成员是v。
union(x,y)将两组x和y联合起来。新集的代表性元素选自两个集合之一
get_representatve(v)返回给定节点所属集合的代表。
在图表中查找连通分量G =(V,E):
foreach vertex v in V:
make_set(v)
foreach edge (u, v) in E:
if get_representatve(u) != get_representatve:
union(u, v)
实现必要的功能对于读者来说是一种练习;-)无论如何它对于无向图都可以正常工作,但如果你想要强连接组件,你应该看看Tarjan的算法。
对于并行实现,存在没有工作效率的确定性算法,但存在一些有趣的随机算法。
答案 3 :(得分:0)
是的,有一种算法在图表的大小上是线性的,O(| V | + | E |)。
visited := the empty set
count := 0
for each vertex v in vertices:
if v not in visited:
count++
add v and all nodes reachable from v to visited
return count
答案 4 :(得分:0)
对于无向图,可以使用简单的DFS在O(n)时间内完成。方法如下:
将explore
定义为查找可从给定节点到达的所有节点的过程。这只是一个递归的类似DFS的过程,在每个节点上,您可以找到该节点的所有子节点并将它们推送到堆栈中。
要查找答案,请在任何节点启动DFS并在该节点上启动explore
过程。保持一个整数(比如cc
)并在每次调用时将其传递给explore
过程。另外,保留一个hashmap / dictionary或者将cc
映射到相应的节点。在explore
过程的每个级别,此时将当前节点映射到cc
。每次以递归方式调用探测过程时,将其传递给cc
的相同值。
每次explore
返回DFS循环时,递增cc
并在下次传递该值。完成整个DFS后,您将拥有一个字典,将每个节点映射到相应的连接组件编号。此过程结束时cc
的值可以为您提供图中所连接组件的数量。
这是伪代码:
function explore(node, graph, cc, map){
map(currentNode) = cc
//find all children of current node, and push onto stack.
//mark current node as visited
for i in stack:
explore(i, graph, cc, map)
}
function DFS{
int cc = -1
for node in keysOfGraph:
if not visited:
cc++
explore(node, graph, cc, map)
return cc
}
来自Dasgupta Algorithms(第3.2.3节)