1 function Dijkstra(Graph, source): 2 dist[source] ← 0 // Initialization 3 4 create vertex set Q 5 6 for each vertex v in Graph: 7 if v ≠ source 8 dist[v] ← INFINITY // Unknown distance from source to v 9 prev[v] ← UNDEFINED // Predecessor of v 10 11 Q.add_with_priority(v, dist[v]) 12 13 14 while Q is not empty: // The main loop 15 u ← Q.extract_min() // Remove and return best vertex 16 for each neighbor v of u: // only v that are still in Q 17 alt ← dist[u] + length(u, v) 18 if alt < dist[v] 19 dist[v] ← alt 20 prev[v] ← u 21 Q.decrease_priority(v, alt) 22 23 return dist, prev
时间复杂度
第一层循环(第14行):O(V)
取出Q中最小的元素(第15行):若不用堆则 O(V);若用堆则 O(log V)
第二层循环(第16行):O(E / V)
更新V的当下最短路径:若不用堆则 O(1);若用堆则 O(log V)
综上:
若用堆,O(V * (log V +E / V log V)) = O(V log V + E log V) -> O(E log V)
若不用堆,O(V * (V +E / V * 1)) = O(V^2 + E) -> O(V^2)
procedureBellmanFord(list vertices, list edges, vertex source) // 读入边和节点的列表,并对distance和predecessor写入最短路径 // 初始化图 foreachvertexvinvertices: if v is source then distance[v] := 0// source节点距离为0 else distance[v] := infinity // 其他设置为Inf predecessor[v] := null
// 对每一条边重复操作 for i from 1to size(vertices)-1: for each edge (u, v) with weight w in edges: if distance[u] + w < distance[v]: distance[v] := distance[u] + w predecessor[v] := u
// 检查是否有负权重的环 //for each edge (u, v) with weight w in edges: // if distance[u] + w < distance[v]: // error "含有包含负权重的环"
1 let dist be a |V| × |V| array of minimum distances initialized to ∞ (infinity) 2 for each vertex v 3 dist[v][v] ← 0 4 for each edge (u,v) 5 dist[u][v] ← w(u,v) // the weight of the edge (u,v) 6 for k from 1to |V| 7 for i from 1to |V| 8 for j from 1to |V| 9 if dist[i][j] > dist[i][k] + dist[k][j] 10 dist[i][j] ← dist[i][k] + dist[k][j] 11 endif
classSolution { public: intnetworkDelayTime(vector<vector<int>>& times, int N, int K){ vector<vector<pair<int,int>>> graph(N+1); //(u,v,w) for(constauto& t : times) graph[t[0]].emplace_back(t[1],t[2]); constint inf = 1e9; vector<int> dist(N+1, inf); dist[K] = 0; //(dist[i], i) priority_queue<pair<int,int>, vector<pair<int,int>>, greater<pair<int,int>>> pq; pq.emplace(0, K); vector<int> visited(N+1, 0); while(!pq.empty()) { auto p = pq.top(); pq.pop(); int u = p.second; if(visited[u]) continue; visited[u] = 1; for(auto& to : graph[u]) { int v = to.first; int w = to.second; if(dist[v] > dist[u] + w) { dist[v] = dist[u] + w; pq.emplace(dist[v], v); } } } int ans = *max_element(dist.begin()+1, dist.end()); return ans == inf ? -1 : ans; } };
bellman-ford算法:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
class Solution { public: int networkDelayTime(vector<vector<int>>& times, int N, int K) { constexpr int MAX_TIME = 1e9; vector<int> dist(N, MAX_TIME); dist[K-1] = 0; for(int i=1; i<N; ++i) for(const auto& time : times) { int u = time[0] - 1; int v = time[1] - 1; int w = time[2]; dist[v] = min(dist[v], dist[u] + w); } int max_dist = *max_element(dist.begin(), dist.end()); return max_dist==MAX_TIME ? -1 : max_dist; } };