743. Network Delay Time

问题:

给定n个节点,节点到节点所需要耗费的时间,从给定节点k开始,

最少花多长时间遍历完所有节点。

Example 1:
Input: times = [[2,1,1],[2,3,1],[3,4,1]], n = 4, k = 2
Output: 2

Example 2:
Input: times = [[1,2,1]], n = 2, k = 1
Output: 1

Example 3:
Input: times = [[1,2,1]], n = 2, k = 2
Output: -1
 
Constraints:
1 <= k <= n <= 100
1 <= times.length <= 6000
times[i].length == 3
1 <= ui, vi <= n
ui != vi
0 <= wi <= 100
All the pairs (ui, vi) are unique. (i.e., no multiple edges.)

  

解法:BFS+Dijkstra

有向图的遍历:

queue:到达某个节点node,所需要耗费的时间costtime :{node,costtime}

另外需要dis数组,dis[i]记录从节点k 到达 i 节点的最小耗费时间。

遍历方法:

对于每一个节点cur_n,

获取其所有邻接节点nextn,

如果dis[cur_n]+nextn.costtime<dis[nextn]

那么更新dis[nextn]为更小的:dis[cur_n]+nextn.costtime

同时,将nextn入队:q.push({dis[nextn], nextn});

 

这里我们需要使用优先队列,使得每次处理为队列中花费时间最小的点。

priority_queue<pair<int,int>, vector<pair<int,int>>, greater<pair<int,int>>> q;//des node, time cost

 

最后从dis数组中找到最大值,为最远两个节点的距离,同时也是遍历完整个图,所需的总距离。

若其中存在INT_MAX初始化值,证明有些节点未访问到,此时返回-1。

 

代码参考:

 1 class Solution {
 2 public:
 3     int networkDelayTime(vector<vector<int>>& times, int n, int k) {
 4         vector<vector<pair<int, int>>> graph(n+1);// nextnode, time
 5         vector<int> dis(n+1, INT_MAX);
 6         priority_queue<pair<int,int>, vector<pair<int,int>>, greater<pair<int,int>>> q;//des node, time cost
 7         for(auto t:times) {
 8             graph[t[0]].push_back({t[1],t[2]});
 9         }
10         q.push({0,k});
11         dis[k]=0;
12         dis[0]=0;
13         int cur_n, cur_tc;
14         while(!q.empty()) {
15             int sz = q.size();
16             for(int i=0; i<sz; i++) {
17                 cur_tc = q.top().first;//time cost
18                 cur_n = q.top().second;//node
19                 q.pop();
20                 for(auto nextn:graph[cur_n]) {
21                     if(dis[cur_n] != INT_MAX && dis[nextn.first]>dis[cur_n]+nextn.second) {
22                         dis[nextn.first] = dis[cur_n]+nextn.second;
23                         q.push({dis[nextn.first], nextn.first});
24                     }
25                 }
26             }
27         }
28         int maxdis = *max_element(dis.begin(), dis.end());
29         return maxdis==INT_MAX?-1:maxdis;
30     }
31 };

 

解法二:Bellman Ford

遍历所有节点,根据times数组,

更新dis数组,

dis[i],同上记录从k点到 i 点的最短距离。

t[0]节点已经被更新过的前提下:dis[t[0]]!=INT_MAX

若当前t[1]节点的距离>dis[t[0]]+t[2],那么更新dis[t[1]]为更小的,经过t[0]的路径距离。

 

最终在所有节点距离k中求最大值,若最大值!=INT_MAX(有节点不能到达k),则返回这个最大值,否则返回-1。

 

代码参考:

 1 class Solution {
 2 public:
 3     int networkDelayTime(vector<vector<int>>& times, int n, int k) {
 4         vector<int> dis(n+1, INT_MAX);
 5         dis[k]=0;
 6         dis[0]=0;
 7         for(int i=1; i<n; i++) {
 8             for(auto t:times) {
 9                 int u=t[0], v=t[1], w=t[2];
10                 if(dis[u]!=INT_MAX && dis[v] > dis[u]+w) {
11                     dis[v] = dis[u]+w;
12                 }
13             }
14         }
15         
16         int maxdis = *max_element(dis.begin(), dis.end());
17         return maxdis==INT_MAX?-1:maxdis;
18     }
19 };

 

 

⚠️ 注意,解法二劣于解法一,

因为解法一中,以节点为驱动,

只有距离更小了,才将下一个节点加入待处理节点。

 

posted @ 2021-03-04 17:40  habibah_chang  阅读(57)  评论(0编辑  收藏  举报