743. 网络延迟时间
这题很适合用来练一下
Dijkstra算法模版。
743. 网络延迟时间
1. 代码
int networkDelayTime(int** times, int timesSize, int* timesColSize, int n, int k){
const int inf = 0x3f3f3f3f;
int g[n][n]; // 邻接矩阵
int used[n];
int dist[n];
int res = 0;
memset(g, 0x3f, sizeof(g));
memset(dist, 0x3f, sizeof(dist));
memset(used, 0, sizeof(used));
dist[k-1] = 0;
// 1. 初始化
for (int i = 0; i < timesSize; i ++) {
int x = times[i][0] - 1;
int y = times[i][1] - 1;
g[x][y] = times[i][2];
}
// 2. 遍历n次
for (int j = 0; j < n; j ++ ) {
int x = -1;
// 2.1 找最近的结点
for (int y = 0; y < n; y ++) {
if (!used[y] && (x == -1 || dist[y] < dist[x])) {
x = y;
}
}
used[x] = true;
res = fmax(res, dist[x]);
// 2.2 松弛
for (int y = 0; y < n; y ++ ) {
dist[y] = fmin(dist[y], dist[x] + g[x][y]);
}
}
return res == inf ? -1 : res;
}
2. 初始化
const int inf = 0x3f3f3f3f;
int g[n][n]; // 维护邻接矩阵
int dist[n]; // 最短路径数组
int used[n]; // 标志是否最短
dist[k - 1] = 0; // 从k开始出发
int ans = 0; // 全局答案
memset(g, 0x3f, sizeof(g)); // 全部设置为infty
memset(dist, 0x3f, sizeof(dist)); // 最开始最短路径全部初始化为 infty
memset(used, 0, sizeof(used)); // 标记哪些点已经确定的最短路径
for (int i = 0; i < timesSize; i ++) { // 遍历每一条边
int x = times[i][0] - 1, y = times[i][1] - 1; // x 为入边,y 表示出边
g[x][y] = times[i][2]; // x->y的权值
}
维护的变量如下:
inf:表示无穷大的int值。g:邻接矩阵,初始化为 allinf,后续通过题目给的数据进行初始化。dist:k 到结点i最短路径,初始化为inf,最后一位置为0,按照题目要求 \(k-1\) 为第k个结点,默认置为0。used:标记结点是否被使用过,用于后续寻找迭代的接力结点。ans:全局答案。
注意
0x3f3f3f3f是一个十进制,四个字节。而memset()函数按照字节为单位作为填充,所以后面的memset()中为0x3f,而非0x3f3f3f3f。
3. 主循环
for (int i = 0; i < n; ++i) {
int x = -1;
for (int y = 0; y < n; y ++) { // 遍历所有的结点
if (!used[y] && (x == -1 || dist[y] < dist[x])) {
// 未使用 || (第一次 && y更短)
x = y;
}
}
used[x] = true;
ans = fmax(ans, dist[x]); // 更新全局答案,要求最长的时间
for (int y = 0; y < n; y ++ ) {
dist[y] = fmin(dist[y], dist[x] + g[x][y]); // 进行松弛操作
}
}
return ans == inf ? -1 : ans;
- 最外层:迭代 \(n\) 次。
- 内次第一次循环:遍历所有节点,嗅探最近的不确定结点,将
x标记为已更新。 - 内层第二次循环:松弛
x与其他所有结点。

浙公网安备 33010602011771号