根据您的描述,不相交的树不一定是树。他们可能有周期。它们通常称为components。
解决此问题的方法之一是使用Disjoint Set 的概念。
您的语言环境可能在本机或作为库实现了不相交集,但这里是 Python 中不相交集的实现:
# Implementation of Union-Find (Disjoint Set)
class Node:
def __init__(self):
self.parent = self
self.rank = 0
def find(self):
if self.parent.parent != self.parent:
self.parent = self.parent.find()
return self.parent
def union(self, other):
node = self.find()
other = other.find()
if node == other:
return True # was already in same set
if node.rank > other.rank:
node, other = other, node
node.parent = other
other.rank = max(other.rank, node.rank + 1)
return False # was not in same set, but now is
所以以上是通用的,与您的图形问题没有特别关系。现在要将它用于您的图,我们为每个图节点创建一个Node 实例,并调用union 来指示连接的节点属于同一个图组件:
def count_components(nodeids, edges):
# Create dictionary of nodes, keyed by their IDs
nodes = {
nodeid: Node() for nodeid in nodeids
}
# All connected nodes belong to the same disjoined set:
for a, b in edges:
nodes[a].union(nodes[b])
# Count distinct roots to which each node links
return len(set(node.find() for node in nodes.values()))
我们可以为您的示例图运行它,如下所示:
vertices = [1,2,3,4,5,6,7,8,9]
edges = [(2,3), (2,7), (3,7), (4,3), (5,1), (5,6)]
print(count_components(vertices, edges)) # 4
由于这些已识别的不相交集,因此打印 4:
{2,3,4,7}
{1,5,6}
{8}
{9}