📜  门| GATE-CS-2007 |问题26(1)

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

问题描述

鉴于大家都喜欢快递,作为程序员,我们也需要编写一个关于快递的程序。给定一个记录快递运输的日志,日志中记录了每个包裹的来源地和目的地。我们需要编写一个程序,判断这些包裹是否可以从源头到达目的地。

输入格式

输入的第一行包含两个正整数,n和m,分别表示快递的数量和运输记录的数量。接下来m行,每行包含两个字符串a和b,表示一个包裹从a运往b。

输出格式

输出共一行,如果所有的包裹都可以从源头到达目的地,则输出"Possible",否则输出"Impossible"。

输入样例

5 4
A B
B C
B D
E B

输出样例

Possible

解题思路

可以使用图论中的拓扑排序思想进行求解。首先,需要将所有的货物存储在一个数组中,数组下标对应货物的来源地。然后遍历运输记录,通过建图的方式,将货物看做是由源头到目的地的一条边。最后对建好的图进行拓扑排序,如果排序后的结果中所有节点都被访问到,则说明所有的货物都可以从源头到达目的地。

以下是代码实现:

n, m = map(int, input().split())

# 初始化图
graph = {i: [] for i in range(n)}

# 添加边
for i in range(m):
    a, b = input().split()
    graph[ord(a) - ord('A')].append(ord(b) - ord('A'))

# 拓扑排序
stack = []
visited = [0] * n

for i in range(n):
    if not visited[i]:
        stack.append(i)
        while stack:
            node = stack[-1]
            visited[node] = 1
            for j in graph[node]:
                if not visited[j]:
                    stack.append(j)
            if node == stack[-1]:
                stack.pop()

if sum(visited) == n:
    print('Possible')
else:
    print('Impossible')

代码片段如上,其中graph = {i: [] for i in range(n)}初始化了包含$n$个节点的图。在遍历运输记录时,利用字母的ASCII码来表示节点,其中graph[ord(a) - ord('A')].append(ord(b) - ord('A'))表示从a到b有一条边。

在拓扑排序结束后,只需判断节点是否都被访问到即可判断所有货物是否可以从源头到达目的地。