743. Network Delay Time
There are N network nodes, labelled 1 to N.
Given times, a list of travel times as directed edges times[i] = (u, v, w), where u is the source node, v is the target node, and w is the time it takes for a signal to travel from source to target.
Now, we send a signal from a certain node K. How long will it take for all nodes to receive the signal? If it is impossible, return -1.
Example 1:
Input: times = [[2,1,1],[2,3,1],[3,4,1]], N = 4, K = 2
Output: 2
Note:
很显然,这一题用Dijkstra法解决,这个算法请参考《算法图解》第七章。这一题,我们要思考两个问题:
我们先来看看Dijkstra算法的步骤:(稍后来具体解释)
由上面的分析,可以得出需要一个数组和一个hash表(可以用其他方式替代),加上表示图邻接表,我们一共需要三张表
vector>> graph
)
vector dis
)unordered_set hash
)这里用一个简单的例子和图来说明吧,遍历完所有的节点,然后找到路径长度表中最长的路径长度即为题目中的网络延迟时间了。
class Solution {
public:
int networkDelayTime(vector<vector<int>>& times, int N, int K) {
vector<vector<pair<int, int>> > graph(N+1);
vector<int> dis(N+1, INT_MAX);
unordered_set<int> hash;
//create graph and init dis
for (auto edge : times){
graph[edge[0]].push_back(make_pair(edge[1], edge[2]));
}
dis[K] = 0;
int cur = K;
while (cur > 0){
hash.insert(cur);
int cur_dis = dis[cur];
for (auto node : graph[cur]){
int node_dis = cur_dis + node.second;
if (node_dis < dis[node.first] && hash.find(node.first) == hash.end()){
dis[node.first] = node_dis;
}
}
//find the next node
int tmp = INT_MAX;
cur = -1;
for (int i=1; i<=N; i++){
if (dis[i]<tmp && hash.find(i)==hash.end()){
tmp = dis[i];
cur = i;
}
}
}
int maxRes = 0;
for (int i=1; i<=N; i++){
maxRes = max(maxRes, dis[i]);
}
return maxRes == INT_MAX? -1 : maxRes;
}
};
上面的解法,时间复杂度一般,空间复杂度更是感人,看看有什么可以优化的地方。
找下一个节点时,每次都用一遍循环,这里我们每次只想找最小,所以可以用最小堆来优化这个地方。
class Solution {
public:
int networkDelayTime(vector<vector<int>>& times, int N, int K) {
vector<vector<pair<int, int>> > graph(N+1);
vector<int> dis(N+1, INT_MAX);
unordered_set<int> hash;
priority_queue<pair<int, int>, vector<pair<int, int>>, greater<pair<int, int>>> node_heap;
//create graph and init dis
for (auto edge : times){
graph[edge[0]].push_back(make_pair(edge[1], edge[2]));
}
dis[K] = 0;
node_heap.emplace(0, K);
while (!node_heap.empty()){
int cur = node_heap.top().second;
node_heap.pop();
hash.insert(cur);
int cur_dis = dis[cur];
for (auto node : graph[cur]){
int node_dis = cur_dis + node.second;
if (node_dis < dis[node.first] && hash.find(node.first) == hash.end()){
dis[node.first] = node_dis;
node_heap.emplace(node_dis, node.first);
}
}
//find the next node
int tmp = INT_MAX;
cur = -1;
for (int i=1; i<=N; i++){
if (dis[i]<tmp && hash.find(i)==hash.end()){
tmp = dis[i];
cur = i;
}
}
}
int maxRes = 0;
for (int i=1; i<=N; i++){
maxRes = max(maxRes, dis[i]);
}
return maxRes == INT_MAX? -1 : maxRes;
}
};