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:邻接矩阵,初始化为 all inf,后续通过题目给的数据进行初始化。
  • 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 与其他所有结点。
posted @ 2026-05-16 00:45  syn_tax  阅读(3)  评论(0)    收藏  举报