执行结果:通过
执行用时和内存消耗如下:
const int INF = 0x3f3f3f3f;
// function declaration
void displayAdjMatrix(int*, int n);
int dijkstra(const int*, const int, const int);
int networkDelayTime(int** times, int timesSize, int* timesColSize, int n, int k) {
// initialize
int adjMatrix[n + 1][n + 1];
memset(adjMatrix, INF, sizeof adjMatrix);
for (int i = 0; i < timesSize; ++i) {
const int u = *(*(times + i));
const int v = *(*(times + i) + 1);
const int w = *(*(times + i) + 2);
*(*(adjMatrix + u) + v) = w;
}
// displayAdjMatrix((int*) adjMatrix, n + 1);
return dijkstra((int*) adjMatrix, n, k);
}
int dijkstra(const int* adjMatrix, const int n, const int s) {
int dists[n + 1], seen[n + 1];
memset(dists, INF, sizeof dists);
memset(seen, 0, sizeof seen);
dists[s] = 0;
for (; ;) {
// step1: 从所有未选中的顶点中选取一个离源点最近的顶点
int min_dist = INF, selected = -1;
for (int i = 1; i <= n; ++i) {
if (!*(seen + i) && *(dists + i) < min_dist) {
min_dist = *(dists + i);
selected = i;
}
}
if (selected == -1) break;
// step2: 选取该顶点
*(seen + selected) = 1;
// step3: 从选中的顶点出发,与其相领的顶点进行松驰操作!
for (int j = 1; j <= n; ++j)
if (*(dists + selected) + *(adjMatrix + selected * (n + 1) + j) < *(dists + j))
*(dists + j) = *(dists + selected) + *(adjMatrix + selected * (n + 1) + j);
}
int max_time = 0;
for (int i = 1; i <= n; ++i) {
if (*(dists + i) == INF) return -1;
if (*(dists + i) > max_time) max_time = *(dists + i);
}
return max_time;
}
void displayAdjMatrix(int* mat, int n) {
for (int i = 1; i < n; ++i) {
for (int j = 1; j < n; ++j)
printf("%d ", *(mat + i * n + j));
putchar('\n');
}
}
解题思路:
这段代码的主要目的是计算一个网络中从指定节点 k
到所有其他节点的最短路径中的最长路径长度,即网络延迟时间。它使用了 Dijkstra 算法来实现这一目的。以下是代码的思路解析:
1. 初始化
INF
(无穷大)定义为0x3f3f3f3f
,这是一个常用的技巧,用于表示一个很大的数,以便在后续比较中判断某个路径是否不可达。- 定义一个邻接矩阵
adjMatrix
来表示图的连接关系,矩阵的大小为(n + 1) x (n + 1)
,其中n
是节点的数量。矩阵的初始值全部设置为INF
,表示任意两点间初始时都是不可达的。 memset
函数用于将内存块中的数据设置为指定的值,这里用于初始化adjMatrix
、dists
和seen
数组。
2. 构建邻接矩阵
- 遍历
times
数组,该数组包含了图中所有边的信息,每个元素是一个三元组(u, v, w)
,表示从节点u
到节点v
有一条权重为w
的边。 - 根据
times
数组的信息,更新adjMatrix
,将实际存在的边的权重设置为对应的w
值。
3. Dijkstra 算法
- 初始化
dists
数组,用于存储从源节点s
到其他所有节点的最短路径长度,初始时除了源节点s
的值为0
外,其余节点的值均为INF
。 - 初始化
seen
数组,用于标记节点是否已经被处理过,初始时所有节点的值均为0
(未处理)。 - 算法的核心是一个循环,每次从未处理的节点中选择一个距离源节点最近的节点,并更新其邻居节点的最短路径长度(即进行松弛操作)。
- 循环直到所有节点都被处理过(即
selected
变量为-1
)。 - 在所有节点处理完毕后,遍历
dists
数组,找到最长的路径长度max_time
。如果某个节点的最短路径长度仍为INF
,则表示该节点不可达,返回-1
。
4. 辅助函数
displayAdjMatrix
函数用于打印邻接矩阵,便于调试和验证。
5. 主函数 networkDelayTime
- 初始化邻接矩阵。
- 根据
times
数组构建邻接矩阵。 - 调用
dijkstra
函数计算从节点k
到所有其他节点的最短路径中的最长路径长度。 - 返回计算结果。
总结:
这段代码通过 Dijkstra 算法计算了给定网络中从指定节点 k
到所有其他节点的最短路径中的最长路径长度,即网络延迟时间。它首先根据输入数据构建了图的邻接矩阵表示,然后应用 Dijkstra 算法找到最短路径,并返回最长路径的长度。如果网络中存在不可达的节点,则返回 -1
。