📅  最后修改于: 2023-12-03 15:42:22.649000             🧑  作者: Mango
本题为 "门" 问题,是计算机科学经典问题之一。题目来源为 门 | 门CS 2011 的第 53 题。
该问题主要考察了图论的算法,涉及图的遍历和深度优先搜索(DFS)算法。该问题通常用于训练计算机科学和算法的竞赛和编程挑战。
有一张 $n$ 个节点和 $m$ 条边的无向图,其中每个节点都标记有数字 $a_i$,$i \in [1, n]$。现在有如下两种操作:
输入数据格式:第一行包含 $n$ 和 $m$,接下来 $n$ 行,每行一个整数,表示每个节点 $a_i$ 的初始值,最后 $m$ 行,每行包含两个整数 $u$ 和 $v$,表示一条无向边 $(u,v)$。
输出数据格式:每输入一个询问,输出一行一个整数,表示查询得到的最短距离。如果不能到达,则输出 -1。
数据范围:
$1 \leq n \leq 10^5$
$1 \leq m \leq 2 \times 10^5$
首先,我们需要知道确定一条最短路径的方法。通常,我们使用 BFS(广度优先搜索)或 Dijkstra 算法来解决这个问题。
不过,本题中的最短路径问题有一个特殊的要求,即要求路径上所有节点的 $a_i$ 的乘积值。
这启示我们对 BFS 或 Dijkstra 算法进行修改。为了强制所有路径上的节点都必须被遍历到,我们可以使用 DFS 算法来实现最短路径的搜索。
而此时,我们需要记录搜索路径上所有节点的 $a_i$ 值的乘积值。DFS 算法的搜索过程中,我们可以将当前节点的 $a_i$ 值乘到已有的乘积中,直到搜索到目标节点。这一乘积值就是最短路径的乘积值。
我们可以采用以下步骤来实现本题:
需要注意的是,由于本题中起点和终点都是动态变化的,因此在运行 DFS 算法时,我们需要对每个询问都重新运行一次搜索算法,而不能预先计算出所有的最短路径。
在本算法中,在最坏情况下,我们需要对每个询问重新运行一次深度优先搜索算法。因此,算法的时间复杂度是 $O(q \times (n + m))$,其中 $q$ 是查询的次数,$n$ 是节点数,$m$ 是边数。
可以参考以下伪代码实现:
# 邻接表
graph = [[] for i in range(n+1)]
for i in range(m):
u, v = map(int, input().split())
graph[u].append((v, 1))
graph[v].append((u, 1))
# 深度优先搜索
def dfs(s, t):
visited = [False]*(n+1)
product = 1
stack = [(s, product)]
while stack:
node, p = stack.pop()
if visited[node]:
continue
visited[node] = True
product *= a[node]
if node == t:
return product
for next_node, weight in graph[node]:
stack.append((next_node, product*weight))
return -1
# 查询
for i in range(q):
s, t = map(int, input().split())
result = dfs(s, t)
print(result)
以上是Python实现的伪代码,具体代码实现可根据实际需要进行修改。