📜  门| GATE-CS-2003 |问题23(1)

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

门 | GATE-CS-2003 | 问题23

问题描述:

考虑一个电路,其中每个门都有一个开放时间和一个关闭时间。如果在一个门的开放时间内到达的信号的值改变了,那么这个值会被转发到下一个门上。在一个门关闭之后,它不再转发信号。一个门的转发时间是0。给定一组开放时间和关闭时间,在这个电路中计算信号从第一个门到最后一个门所需的最短时间。

以以下格式输入电路信息:

n(电路中的门数)
o1 c1 (第1个门的开放时间和关闭时间)
.
.
on cn (第n个门的开放时间和关闭时间)

其中,n是一个正整数,表示电路中的门数。o1 c1on cn 是每个门的开放时间和关闭时间。所有时间值都是非负整数值。

示例:

输入:

3
1 2
2 3
3 3

输出:

5
思路:

本问题是一个经典的最短路问题。可以用Dijkstra算法求解。对于每个门,都可以看做是一个节点,并且相邻的节点有一条边权为开放时间的边连接。可以通过维护一个优先队列来进行最短路的计算。具体步骤如下:

  1. 初始化所有门的距离为正无穷,起始门的距离为0.
  2. 将起始门加入优先队列中.
  3. 不断从优先队列中取出距离最小的门,更新与该门相邻的门的距离,将新的门加入优先队列.
  4. 重复步骤3,直到队列为空或者目标门的距离被更新.
代码实现:
import heapq

def dijkstra(graph, start, end):
    # 初始化距离为正无穷
    distances = {vertex: float('inf') for vertex in graph}
    # 起始门距离为0
    distances[start] = 0
    # 初始化优先队列
    pq = [(0, start)]
    while pq:
        # 取出距离最小的门
        current_distance, current_vertex = heapq.heappop(pq)
        # 跳过已经走过的点
        if current_distance > distances[current_vertex]:
            continue
        # 更新与该门相邻的门的距离
        for neighbor, weight in graph[current_vertex].items():
            distance = current_distance + weight
            if distance < distances[neighbor]:
                distances[neighbor] = distance
                heapq.heappush(pq, (distance, neighbor))
        # 目标门的距离被更新
        if current_vertex == end:
            return distances[end]
    # 队列为空,无法到达目标门
    return float('inf')

if __name__ == '__main__':
    n = int(input())
    gates = {}
    for i in range(1, n+1):
        o, c = map(int, input().split())
        gates[i] = {'open_time': o, 'close_time': c}
    # 构建门之间的连边
    graph = {}
    for i in range(1, n+1):
        graph[i] = {}
        for j in range(i+1, n+1):
            if gates[i]['close_time'] + abs(i-j) + gates[j]['open_time'] <= gates[j]['close_time']:
                graph[i][j] = abs(i-j)
    # 计算起始门(1)到目标门(n)的最短路
    print(dijkstra(graph, 1, n))
Markdown代码片段
```python
import heapq

def dijkstra(graph, start, end):
    # 初始化距离为正无穷
    distances = {vertex: float('inf') for vertex in graph}
    # 起始门距离为0
    distances[start] = 0
    # 初始化优先队列
    pq = [(0, start)]
    while pq:
        # 取出距离最小的门
        current_distance, current_vertex = heapq.heappop(pq)
        # 跳过已经走过的点
        if current_distance > distances[current_vertex]:
            continue
        # 更新与该门相邻的门的距离
        for neighbor, weight in graph[current_vertex].items():
            distance = current_distance + weight
            if distance < distances[neighbor]:
                distances[neighbor] = distance
                heapq.heappush(pq, (distance, neighbor))
        # 目标门的距离被更新
        if current_vertex == end:
            return distances[end]
    # 队列为空,无法到达目标门
    return float('inf')

if __name__ == '__main__':
    n = int(input())
    gates = {}
    for i in range(1, n+1):
        o, c = map(int, input().split())
        gates[i] = {'open_time': o, 'close_time': c}
    # 构建门之间的连边
    graph = {}
    for i in range(1, n+1):
        graph[i] = {}
        for j in range(i+1, n+1):
            if gates[i]['close_time'] + abs(i-j) + gates[j]['open_time'] <= gates[j]['close_time']:
                graph[i][j] = abs(i-j)
    # 计算起始门(1)到目标门(n)的最短路
    print(dijkstra(graph, 1, n))