📜  门|门CS 2013 |问题 19(1)

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

门|门CS 2013 |问题 19

这是一道关于图论的问题。给定一个有向图,其中每个节点都被标记为“门”或“非门”。一个节点是“门”,当且仅当它没有任何入度。现在,给定一个起点和终点,请你计算从起点到终点的最短路径,其中只能经过“门”。

问题分析

首先,我们需要读入图,并将图中每个节点分为两类:门和非门。有门的节点是起点,没有门的节点是终点。接下来,我们可以使用广度优先搜索(BFS)算法,从起点开始遍历图。

具体来说,我们从起点开始,检查它是否为门。如果是,我们将其标记为已访问,并加入待访问队列。对于每个已访问的门节点,我们将其所有未被访问的邻居节点加入待访问队列中,并将它们标记为已访问。为了避免重复访问,可以使用一个 visited 数组来记录已经访问过的节点。

在遍历的过程中,我们可以使用一个 distance 数组来记录每个节点到起点的距离。当我们访问到终点时,我们就找到了一条从起点到终点的路径,记录距离即可。

代码实现
from collections import deque

# 读入图
n, m = map(int, input().split())
graph = [[] for _ in range(n)]
for _ in range(m):
    u, v = map(int, input().split())
    graph[u-1].append(v-1)

# 标记门和非门
is_gate = [True] + [False]*(n-1)
for i in range(n):
    for v in graph[i]:
        if is_gate[v]:
            is_gate[i] = False
            break

# BFS
start, end = None, None
for i, gate in enumerate(is_gate):
    if gate:
        if start is None:
            start = i
        else:
            end = i
distance = [-1]*n
distance[start] = 0
visited = [False]*n
visited[start] = True
q = deque([start])
while q:
    u = q.popleft()
    for v in graph[u]:
        if not visited[v]:
            visited[v] = True
            distance[v] = distance[u] + 1
            q.append(v)
path_length = distance[end]

# 输出结果
print(path_length)

以上代码首先读入图的信息,并使用一个列表 is_gate 记录每个节点是否为门。然后,在遍历图的过程中,我们使用数组 distance 记录每个节点到起点的距离,使用一个队列 q 记录待访问的节点,以及一个 visited 数组记录每个节点是否已经被访问过。

最后,我们输出起点到终点的最短路径长度(如果有解)。