📜  门| GATE 2017 MOCK II |第 35 题(1)

📅  最后修改于: 2023-12-03 15:12:34.972000             🧑  作者: Mango

GATE 2017 MOCK II | 第 35 题

这是一道关于图的问题,题目要求我们使用最小代价树的算法对图进行操作,以保证其连通且代价最小。

具体来说,我们需要用到 Kruskal 算法或 Prim 算法,它们都能求得最小代价树,区别在于 Kruskal 算法先将边按代价从小到大排序,再按顺序选取边,Prim 算法起点随意,每次选择距离当前生成树最近的点加入生成树。

我们可以使用 Python 来实现 Kruskal 算法,首先需要将边按代价从小到大排序,然后从小到大选取边,加入生成树,直到所有点都被包含在生成树中为止。

def find(parent, i): 
    if parent[i] == i: 
        return i 
    return find(parent, parent[i]) 
    
def union(parent, rank, x, y): 
    xroot = find(parent, x) 
    yroot = 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
        
def kruskal(graph, V): 
    result =[] 
    i = 0 
    e = 0 
    graph =  sorted(graph,key=lambda item: item[2]) 
    parent = [] ; rank = [] 
    for node in range(V): 
        parent.append(node) 
        rank.append(0)    
    while e < V -1 : 
        u,v,w =  graph[i] 
        i = i + 1
        x = find(parent, u) 
        y = find(parent ,v) 
        if x != y: 
            e = e + 1     
            result.append([u,v,w]) 
            union(parent, rank, x, y)         
    return result

这个函数的输入包括了待操作的图以及点的数量,返回的是最小代价树。

对于 Prim 算法,我们可以使用 heapq 模块,先从起点开始,将与起点相邻的所有边加入 heap,每次从 heap 中取出代价最小的边加入生成树,直到所有点都被包含在生成树中为止。

import heapq 

def primMST(adj, V): 
    pq = [] 
    heapq.heappush(pq, (0, 0)) 
    visited = [False] * V 
    ans = 0
    while len(pq) > 0:  
        cur = heapq.heappop(pq) 
        u = cur[1] 
        if visited[u]: 
            continue 
        visited[u] = True
        ans += cur[0] 
        for neigh in adj[u]: 
            v = neigh[0] 
            if not visited[v]: 
                heapq.heappush(pq, (neigh[1], v)) 
    return ans

这个函数的输入包括了待操作的图以及点的数量,返回的是最小代价树的总代价。

总之,这道题涉及到了图的基本算法,需要对它们有比较好的掌握,才能对图的问题有更好的解决方案。