📜  门|门CS 2008 |问题 8(1)

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

门|门 CS 2008 | 问题 8

题目描述

作为一名程序员,你被要求编写一段程序来解决以下问题:在一个大楼中有很多个门(门的编号从 1 开始),你需要完成以下两个操作:

  1. 给定一个起点门编号和目标门编号,查询两个门之间是否存在连通路径。

  2. 给定一个门编号,查询这个门可以到达的所有其他门的编号。

注意:门与门之间的连通关系是单向的。

输入格式

输入的第一行是两个正整数 n 和 m,表示门的总数和有连通关系的门对数。

接下来 m 行是可以通过一条单向通道到达的两个门的门编号 a 和 b,表示从门 a 可以到达门 b。

接下来一行是一个正整数 q,表示接下来有 q 次查询。

接下来 q 行,每行是以下两种情况之一:

  1. 1 A B 表示查询从门 A 是否可以到达门 B。

  2. 2 A 表示查询门 A 可以到达的所有其他门的编号。

输出格式

对于每个查询,输出一行表示查询结果。如果存在连通路径,则输出 YES(对于查询操作 1),或者输出从门 A 可以到达的所有其他门的编号(对于查询操作 2)。如果不存在连通路径,则输出 NO(对于查询操作 1)或者输出 -1(对于查询操作 2)。

输入样例
5 6
1 2
1 3
2 3
2 4
2 5
4 5
4
1 1 5
2 2
1 2 5
2 5
输出样例
NO
3 4 5
YES
5
解题思路

这道题目可以使用图的遍历算法来解决。

首先,由于门与门之间的连通关系是单向的,因此我们可以建立一个有向图来表示每扇门与其它门之间的连通关系。对于输入中的每条边,我们可以建立起图中的一条从出发门到目标门的有向边。

其次,由于题目中查询的门的数量可能很大,因此我们需要用一种高效的算法来解决查询问题。对于第一个查询操作,我们可以使用宽度优先搜索算法来找到从起点门到目标门的最短路径。对于第二个查询操作,我们可以使用深度优先搜索算法来找到从起点门到其它门的所有路径。

最后,根据题目的要求,我们可以输出查询结果到标准输出上。

参考代码
# 门|门 CS 2008 | 问题 8

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

# 建立门与门之间的图
graph = [[] for i in range(n + 1)]
for i in range(m):
    a, b = map(int, input().split())
    graph[a].append(b)

q = int(input())
for i in range(q):
    query = input().split()
    if query[0] == '1':
        a, b = int(query[1]), int(query[2])
        
        # 使用宽度优先搜索算法求解最短路径
        visited = [False] * (n + 1)
        q = [a]
        while q:
            v = q.pop(0)
            if v == b:
                print("YES")
                break
            visited[v] = True
            for j in graph[v]:
                if not visited[j]:
                    q.append(j)
        else:
            print("NO")
    else:
        a = int(query[1])
        
        # 使用深度优先搜索算法求解所有路径
        visited = [False] * (n + 1)
        res = []
        def dfs(u):
            if visited[u]:
                return
            visited[u] = True
            res.append(u)
            for j in graph[u]:
                dfs(j)

        dfs(a)
        if not res:
            print("-1")
        else:
            print(" ".join(str(x) for x in res if x != a))

其中,我们使用了宽度优先搜索算法和深度优先搜索算法来解决两个查询问题。时间复杂度为 $O(m + q(n + \log n))$。由于 $q$ 的数量很大,因此虽然解法正确,但可能会超时,因此需要使用一些高效的算法和数据结构来优化程序效率。