最小高度树(python)

最一道题还算是一个经典的dfs算法题,我希望通过这一道题,能够帮助我们一些初学者,更好的帮助
请添加图片描述
请添加图片描述

创栈和字典

将输入的信息进行转换为一个字典类型,通过python自带的collections.defaultdict 进行整理,并且同过栈将value 为1的放进栈中。

adjs=collections.defaultdict(list)
for x in edges: # 图的邻接表表示法,基本是模板
    adjs[x[0]].append(x[1]) # 1:{2}
    adjs[x[1]].append(x[0]) # 2:{1}
queue = deque() # 固定写法
    for key, value in adjs.items():
        if len(value) == 1:
            queue.append(key)

进行bfs算法

在bfs算法将其叶子节点给删去,和有叶子节点的字典中value删去

 while(queue): # 固定写法
 	size = len(queue)  # 固定写法
	n = n - size
	for _ in range(size):
		v = queue.popleft()
		v_adj = adjs[v].pop() # v的邻接仅一个,弹出即删除
        adjs[v_adj].remove(v) # 在v的邻接元素的邻接列表里删除v
        if len(adjs[v_adj]) == 1:
        	queue.append(v_adj)
记得考虑情况,当n=1,时只有一个数,就是本身,n=2时两个数都可以当根节点,下面是全部的代码
import collections
n=int(input())
edges=[[1,0],[1,2],[1,3]]   #这个是自己随便输入的
if n == 2:
    print([0,1])
if n == 1:
    print([0])
adjs = collections.defaultdict(list) # defaultdict写法很有用
for x in edges: # 图的邻接表表示法,基本是模板
    adjs[x[0]].append(x[1]) # 1:{2}
    adjs[x[1]].append(x[0]) # 2:{1}
# BFS队列: 初始队列放入初始元素,size=1的为叶子,入队
queue = collections.deque() # 固定写法
for key, value in adjs.items():
    if len(value) == 1:
        queue.append(key)
# BFS两个大循环
while(queue): # 固定写法
    size = len(queue)  # 固定写法
    n = n - size
    for _ in range(size):
        v = queue.popleft()
        v_adj = adjs[v].pop() # v的邻接仅一个,弹出即删除
        adjs[v_adj].remove(v) # 在v的邻接元素的邻接列表里删除v
        if len(adjs[v_adj]) == 1:
            queue.append(v_adj)
    if n == 1:
        print( [queue.popleft()])
    if n == 2:
        print([queue.popleft(), queue.popleft()])

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,我可以帮你解决这个问题。首先,为了使用Kruskal算法,我们需要先实现一个无向图类。以下是一个简单的实现: ```python class Graph: def __init__(self, vertices): self.vertices = vertices self.edges = [] def add_edge(self, u, v, w): self.edges.append((u, v, w)) def find(self, parent, i): if parent[i] == i: return i return self.find(parent, parent[i]) def union(self, parent, rank, x, y): xroot = self.find(parent, x) yroot = self.find(parent, y) if rank[xroot] < rank[yroot]: parent[xroot] = yroot elif rank[xroot] > rank[yroot]: parent[yroot] = xroot else: parent[yroot] = xroot rank[xroot] += 1 ``` 其中,`vertices`表示图中所有顶点的列表,`edges`表示图中所有边的列表。`add_edge`方法用于向图中添加一条边,`u`和`v`是边的两个端点,`w`是边的权重。 接下来,我们可以实现Kruskal算法来计算最小生成。以下是实现代码: ```python def kruskal(graph): result = [] i, e = 0, 0 graph.edges = sorted(graph.edges, key=lambda item: item[2]) parent = [] rank = [] for node in range(graph.vertices): parent.append(node) rank.append(0) while e < graph.vertices - 1: u, v, w = graph.edges[i] i = i + 1 x = graph.find(parent, u) y = graph.find(parent, v) if x != y: e = e + 1 result.append((u, v, w)) graph.union(parent, rank, x, y) print("Minimum Spanning Tree:") for u, v, weight in result: print("(%d, %d, %d)" % (u, v, weight)) total_weight = sum(weight for _, _, weight in result) print("Total weight:", total_weight) ``` 在这个实现中,我们首先对图中所有边按权重从小到大进行排序,然后初始化一个空的最小生成列表`result`,以及一个`parent`和一个`rank`列表,用于记录每个顶点所属的集合及其高度。然后,我们循环处理每一条边,如果这条边的两个端点不在同一个集合中,则将它们合并到一个集合中,并将这条边添加到最小生成列表中。最后,我们输出最小生成的每条边及其权重之和。 最后,我们可以在程序中调用`kruskal`函数来计算无向图的最小生成。例如,我们可以这样定义一个无向图: ```python g = Graph(4) g.add_edge(0, 1, 10) g.add_edge(0, 2, 6) g.add_edge(0, 3, 5) g.add_edge(1, 3, 15) g.add_edge(2, 3, 4) kruskal(g) ``` 执行这段代码,程序会输出以下结果: ``` Minimum Spanning Tree: (2, 3, 4) (0, 3, 5) (0, 1, 10) Total weight: 19 ``` 这就是无向图的最小生成及其权重之和。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值