Network Delay Time 網路延遲時間
阿新 • • 發佈:2018-12-11
有 N
個網路節點,標記為 1
到 N
。
給定一個列表 times
,表示訊號經過有向邊的傳遞時間。 times[i] = (u, v, w)
,其中 u
是源節點,v
是目標節點, w
是一個訊號從源節點傳遞到目標節點的時間。
現在,我們向當前的節點 K
傳送了一個訊號。需要多久才能使所有節點都收到訊號?如果不能使所有節點收到訊號,返回 -1
。
注意:
N
的範圍在[1, 100]
之間。K
的範圍在[1, N]
之間。times
的長度在[1, 6000]
之間。- 所有的邊
times[i] = (u, v, w)
都有1 <= u, v <= N
且1 <= w <= 100
思路:這道題其實就是單源最短路勁的問題(即在圖中給定節點K,其他所有節點距離K的距離),主要解法有Dijkstra’s algorithm和Bellman–Ford Algorithm解法。接下來分別說下:
思路一:迪傑斯特拉解法,最常見的解法是不使用任何輔助,類似於BFS每次向外拓展一圈。時間複雜度O(n^2),n表示節點。
參考程式碼:
class Solution { public: int networkDelayTime(vector<vector<int>>& times, int N, int K) { if (times.empty()) return -1; vector<vector<int>> edges(101, vector<int>(101,-1)); vector<int> dict(N + 1, INT_MAX); dict[K] = 0; queue<int> q; q.push(K); for (auto time : times) edges[time[0]][time[1]] = time[2]; while (!q.empty()) { unordered_set<int> visited; for (auto i = q.size(); i > 0; i--) { auto u = q.front(); q.pop(); for (int v = 1; v <= 100; v++) { if (edges[u][v] != -1 && dict[v] > (dict[u] + edges[u][v])) { if (!visited.count(v)) { visited.insert(v); q.push(v); } dict[v] = (dict[u] + edges[u][v]); } } } } int res = 0; for (int i = 1; i <= N; i++) { if (dict[i] == INT_MAX) return -1; res = max(res, dict[i]); } return res; } };
思路二:採用了最小堆,每次從堆中取出距離最短的節點,時間複雜度為O(vlogv)。
參考程式碼:
class Solution { public: struct networkDelayTimeCmp { bool operator()(const pair<int, int> &a, const pair<int, int> &b) { return a.second > b.second; } }; unordered_map<int, vector<vector<int>>> make_graph(vector<vector<int>>& times, int N) { unordered_map<int, vector<vector<int>>> res; for (auto node : times) { if (res.find(node[0]) == res.end()) res[node[0]] = { {node[1],node[2]} }; else { vector<vector<int>> old = res[node[0]]; old.push_back({ node[1],node[2] }); res[node[0]] = old; } } return res; } int networkDelayTime(vector<vector<int>>& times, int N, int K) { if (times.empty()) return -1; priority_queue<pair<int, int>, vector<pair<int, int>>, networkDelayTimeCmp> q; unordered_map<int, vector<vector<int>>> map = make_graph(times, N); vector<int> dict(N+1,INT_MAX); dict[K] = 0; q.push({K,0}); while (!q.empty()) { auto closest = q.top(); q.pop(); if (map.find(closest.first) != map.end()) { for (auto neibors : map[closest.first]) { int v = neibors[0]; int weight = neibors[1]; int u = closest.first; if ((long)(dict[v]) > (long)(dict[u] + weight)) { dict[v] = (dict[u] + weight); q.push({v,dict[v]}); } } } } int res = 0; for (int i = 1; i <= N;i++) { if (dict[i]==INT_MAX) { return -1; } res = max(res, dict[i]); } return res; } };
思路三:最後是bellman演算法,時間複雜度為O(vloge)(v表示節點,e表示邊)
參考程式碼:
class Solution {
public:
int networkDelayTime(vector<vector<int>>& times, int N, int K) {
if (times.empty()) return -1;
vector<int> dict(N + 1, INT_MAX);
dict[K]=0;
for (int i = 1; i < N; i++) {
for (auto time : times) {
int u = time[0], v = time[1], w = time[2];
if (dict[u] != INT_MAX && dict[v] > (dict[u] + w)) {
dict[v] = dict[u] + w;
}
}
}
int res = 0;
for (int i = 1; i <= N; i++) {
if (dict[i] == INT_MAX) return -1;
res = max(res, dict[i]);
}
return res;
}
};