• 100 likes • 262 Views
Shortest Paths. USACO January. Good job to Karen who promoted to Gold Also Johnny, who tied for 3rd place out of the non-perfect scorers in the US. HOUYANG 4 LIFE. Dijkstra. Find the shortest path from a start node to any other node in the graph. Two versions - O(N^2) and O(M log M)
E N D
USACO January Good job to Karen who promoted to Gold Also Johnny, who tied for 3rd place out of the non-perfect scorers in the US. HOUYANG 4 LIFE
Dijkstra • Find the shortest path from a start node to any other node in the graph. • Two versions - O(N^2) and O(M log M) • (N is number of nodes, M is number of edges) • Basic Idea: Beginning from the start node, build a graph by adding a single node each time. • Add the node that is closest to the start node. • For each node not yet added to the graph, keep track of the best distance found so far • Update this when adding other nodes to the graph.
Dijkstra: O(N^2) dst[startnode] = 0; //distance from start to start is 0 for (int i = 0; i < N; ++i) { // find closest unvisited node int cur = -1; for(int j = 0; j < N; ++j) if (!visited[j]) if (cur == -1 || dst[j] < dst[cur]) cur = j; // cur is the node with min. dist. // update its neighbors for(int j = 0; j < N; ++j) if (!visited[j]) { // first go to cur, then go from cur to j. // total dst = dst[cur] + len of edge from cur to j int newdst = dst[cur] + adj[cur][j]; dst[j] = min(dst[j], newdst); } visited[cur] = true; // mark cur as in the graph. }
Dijkstra: O(M log M) typedef pair<int, int> pii; // pii is a pair of two ints. PQ<pii> pq; // PQ is a min-heap priorityqueue. // it stores pair(distance, node) pairs. pq.push(pii(0, start)); while (!pq.empty()) { pii p = pq.top(); pq.pop(); //get top. int cur = p.second; if (vis[cur]) continue; dst[cur] = p.first; repi(i, conn[cur]) { //iterate over edges going from cur int j = i -> second, len = i -> first; int newdst = dst[cur] + len; pq.push(pii(newdst, j)); } vis[cur] = true; }
Floyd Warshall • Find all shortest paths; find the distance from node i to node j for all pairs i,j. • Runs in O(N^3) time. • Basic Idea: Try making a path from i to j by going from i to k, then from k to j. • Pretty tricky to prove • Very simple to code for (int k = 0; k < N; ++k) for(int i = 0; i < N; ++i) for(int j = 0; j < N; ++j) { int newdst = adj[i][k] + adj[k][j]; adj[i][j] = min(adj[i][j], newdst; }
Bellman-Ford • Same as dijkstra, but can also detect negative edge-weight cycles. • O(MN) time • Basic Idea: Relax each edge. Do that N times. • To relax an Edge from a to b with length len, check if dst[a] + len is smaller than dst[b]. • If it is, update dst[b]. • If you are still updating distances after relaxing N times, there is a negative edgeweight cycle somewhere
Bellman Ford: O(NM) for(int i = 0; i <= N; ++i) { for(int j = 0; j < M; ++j) { int newdst = dst[a[j]] + c[j]; if (newdst < dst[b[j]]) { dst[b[j]] = newdst; if (i == N) { //this is the N + 1th time already. return true; // there's a negative edge-weight cycle!! } } } }
POTW • Carlos is sleeping at City A. • John and Nancy ask Carlos to bring shoes to B and C, respectively. • What is the minimum total distance Carlos has to travel to deliver shoes to both John and Nancy? (the order of delivery doesn't matter) • Roads are bidirectional. There are no roads that leads from a city to itself. • Input • 1st line - N (# cities), M (# roads), A, B, C • 2nd - (M+1)th lines - City U, City V, Distance W • Ouput • Shortest distance
Sample Input 3 3 1 2 3 1 2 3 1 3 7 2 3 4 • Sample Output 7