中等
魔导传输网络
图最短路径Floyd
题目描述
帕秋莉正在红魔馆的地下图书馆构建一套魔导传输网络。该网络由 n 个编号为 0 ~ n-1 的魔导单元组成,单元之间通过 m 条双向传输通道进行信息交换。每条通道连接两个特定的单元,并有一定的传输延迟 c。同一对单元之间可能存在多条不同的通道。
咲夜需要协助帕秋莉计算特定单元对之间的最小传输总延迟。如果两个单元之间存在多条路径,找出总延迟之和最小的一条;若两个单元之间没有任何路径相连,则输出 0。
数据范围:
- 1 ≤ n ≤ 100
- 1 ≤ m ≤ n²
- 1 ≤ c ≤ 100
- 1 ≤ k ≤ 10⁴(查询次数)
示例
输入:
5 3
0 1 10
1 2 20
3 4 40
3
0 2
0 3
3 4
输出:
30
0
40
说明:
- 0→1→2 总延迟 = 10+20 = 30
- 0 与 3 不连通,输出 0
- 3↔4 直接连通,总延迟 = 40
解题思路
为什么选 Floyd?
- n ≤ 100 很小,O(n³) = 10⁶ 完全够用
- 查询次数 k ≤ 10⁴,Floyd 预处理后每次 O(1) 查表,远优于每次 Dijkstra
Floyd-Warshall 算法:
核心三重循环:
for k in 0..n-1: // 枚举中转点
for i in 0..n-1: // 枚举起点
for j in 0..n-1: // 枚举终点
dist[i][j] = min(dist[i][j], dist[i][k] + dist[k][j])
含义:尝试经过节点 k 中转,看是否能缩短 i 到 j 的距离。
初始化:
dist[i][i] = 0dist[i][j] = c(直接相连的边,重边取最小)- 其余为 Infinity
代码实现
function floyd(n, edges) {
const INF = Infinity;
const dist = Array.from({ length: n }, (_, i) =>
Array.from({ length: n }, (_, j) => (i === j ? 0 : INF))
);
// 填入边(重边取最小)
for (const [a, b, c] of edges) {
if (c < dist[a][b]) {
dist[a][b] = c;
dist[b][a] = c; // 无向图
}
}
// Floyd 核心:枚举中转点 k
for (let k = 0; k < n; k++) {
for (let i = 0; i < n; i++) {
if (dist[i][k] === INF) continue; // 剪枝
for (let j = 0; j < n; j++) {
const through = dist[i][k] + dist[k][j];
if (through < dist[i][j]) {
dist[i][j] = through;
}
}
}
}
return dist;
}
// 主流程
function solve(n, edges, queries) {
const dist = floyd(n, edges);
return queries.map(([i, j]) => {
const d = dist[i][j];
return d === Infinity ? 0 : d;
});
}
拓展:Dijkstra 堆优化版
如果只有少量查询,也可以用 Dijkstra 堆优化(O((n+m) log n) per query)。
function dijkstraHeap(n, graph, start) {
const INF = Infinity;
const dist = new Array(n).fill(INF);
dist[start] = 0;
const heap = [[0, start]]; // [距离, 节点]
while (heap.length > 0) {
const [d, u] = heapPop(heap);
if (d > dist[u]) continue; // 懒删除
for (let v = 0; v < n; v++) {
if (graph[u][v] === INF) continue;
const newDist = dist[u] + graph[u][v];
if (newDist < dist[v]) {
dist[v] = newDist;
heapPush(heap, [newDist, v]);
}
}
}
return dist;
}
复杂度分析
- 时间复杂度: O(n³ + k),Floyd 预处理 O(n³),k 次查询每次 O(1)。
- 空间复杂度: O(n²),存储距离矩阵。
示例输入 / 输出
下面给出一组输入输出示例,便于对照题意与结果。
编号 magic-network难度 中等
输入
5 3 0 1 10 1 2 20 3 4 40 3 0 2 0 3 3 4
输出
30 0 40