问题:
给定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 };
⚠️ 注意,解法二劣于解法一,
因为解法一中,以节点为驱动,
只有距离更小了,才将下一个节点加入待处理节点。