📜  门| GATE CS 2010 |问题28(1)

📅  最后修改于: 2023-12-03 14:58:19.422000             🧑  作者: Mango

门 | GATE CS 2010 | 问题28

该问题需要你设计一个算法,在给定的图中寻找是否存在从一个点到另一个点的路径,使得该路径上的边的权重都不小于一个给定的值。

输入格式
  • 一个整数 $n$,表示节点的数量;
  • 一个整数 $m$,表示边的数量;
  • $m$ 行输入,每行包含三个整数 $u$、$v$、$w$,表示一条从节点 $u$ 到节点 $v$ 的边,边的权重为 $w$;
  • 一个整数 $q$,表示查询的数量;
  • $q$ 行输入,每行包含三个整数 $u$、$v$、$w$,表示询问从节点 $u$ 到节点 $v$ 是否存在一条路径,使得该路径上的边的权重都不小于 $w$。
输出格式

对于每个询问,输出一行表示从节点 $u$ 到节点 $v$ 是否存在一条路径,如果存在则输出 “Yes”,否则输出 “No”。

解题思路

本题考察的是图的最短路算法。具体来说,可以使用 Dijkstra 算法或者 Bellman-Ford 算法来解决以下问题:

对于每个询问 $(u,v,w)$,使用 Dijkstra 算法或者 Bellman-Ford 算法求出从节点 $u$ 到所有其他节点的最短路,然后判断是否存在从 $u$ 到 $v$ 的一条路径,使得该路径上的边的权重都不小于 $w$。

如果存在这样的路径,输出 “Yes”;否则输出 “No”。

时间复杂度为 $O(q(m\log n))$,其中 $q$ 表示询问的数量,$(m\log n)$ 表示使用 Dijkstra 算法或者 Bellman-Ford 算法求解最短路的时间复杂度。

代码示例

下面的代码示例使用了 Dijkstra 算法来解决该问题。

import heapq

def dijkstra(graph, start):
    n = len(graph)
    dist = [float('inf')] * n
    dist[start] = 0
    visited = set()
    heap = [(0, start)]
    
    while heap:
        d, u = heapq.heappop(heap)
        
        if u in visited:
            continue
        
        visited.add(u)
        
        for v, w in graph[u]:
            if dist[u] + w < dist[v]:
                dist[v] = dist[u] + w
                heapq.heappush(heap, (dist[v], v))
    
    return dist

def solve(n, m, edges, q, queries):
    graph = [[] for _ in range(n)]
    
    for u, v, w in edges:
        graph[u].append((v, w))
        graph[v].append((u, w))
        
    for u, v, w in queries:
        dist = dijkstra(graph, u)
        
        if dist[v] <= w:
            print('Yes')
        else:
            print('No')
备注

以上代码使用了堆优化的 Dijkstra 算法,时间复杂度为 $O(m\log n)$。如果采用 Bellman-Ford 算法,时间复杂度为 $O(q(mn))$。