mirror of
https://github.com/iritmaximus/tira.git
synced 2026-10-12 19:13:47 +03:00
61 lines
1.4 KiB
Python
61 lines
1.4 KiB
Python
class UnionFind:
|
|
def __init__(self, nodes):
|
|
self.link = {node: None for node in nodes}
|
|
self.size = {node: 1 for node in nodes}
|
|
|
|
def find(self, x):
|
|
while self.link[x]:
|
|
x = self.link[x]
|
|
return x
|
|
|
|
def union(self, a, b):
|
|
a = self.find(a)
|
|
b = self.find(b)
|
|
if a == b:
|
|
return
|
|
|
|
if self.size[a] > self.size[b]:
|
|
a, b = b, a
|
|
self.link[a] = b
|
|
self.size[b] += self.size[a]
|
|
|
|
class Kruskal:
|
|
def __init__(self, nodes):
|
|
self.nodes = nodes
|
|
self.edges = []
|
|
|
|
def add_edge(self, node_a, node_b, weight):
|
|
self.edges.append((node_a, node_b, weight))
|
|
|
|
def construct(self):
|
|
self.edges.sort(key=lambda x: -x[2])
|
|
|
|
uf = UnionFind(self.nodes)
|
|
edges_count = 0
|
|
tree_weight = 0
|
|
|
|
for edge in self.edges:
|
|
node_a, node_b, weight = edge
|
|
if uf.find(node_a) != uf.find(node_b):
|
|
print(node_a, node_b)
|
|
uf.union(node_a, node_b)
|
|
edges_count += 1
|
|
tree_weight += weight
|
|
|
|
if edges_count != len(self.nodes) - 1:
|
|
return None
|
|
return tree_weight
|
|
|
|
def main():
|
|
nodes = [x for x in range(1,1000+1)]
|
|
k = Kruskal(nodes)
|
|
for i in nodes:
|
|
for j in range(1,i):
|
|
k.add_edge(j, i, min(i, j))
|
|
|
|
print(k.construct())
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main()
|