The following methods can be used to find the shortest path: dijkstra, spfa, floyd, and dijkstraspfa.

Source: Internet
Author: User

The following methods can be used to find the shortest path: dijkstra, spfa, floyd, and dijkstraspfa.

Some things can't be solved for a long time, so I recently learned the shortest path algorithm and hope I can make it easier.

Dijkstra is a single-source shortest path algorithm. In the absence of negative weights, if vi... vj... vk is the shortest path from vi to vk, it must take the shortest path from vi to vj. Therefore, each time the vertex with the smallest distance is retrieved, the distance of the vertex adjacent to the vertex is updated from the vertex. If the vertex is updated successfully, the new vertex is added to priority_queue. Graph storage uses an adjacent table. The Code is as follows:

# Include <bits/stdc ++. h> // Directed Graph using namespace std; // dijkstra is not applicable to graphs with negative weights. const int maxn = 1007, maxm = 20007, INF = 2147483467; // maxn is slightly larger than the top point, maxm is slightly larger than the number of edges. int head [maxn], vis [maxn], dis [maxn], fa [maxn]; int next [maxm], u [maxm], v [maxm], w [maxm]; typedef pair <int, int> pi; // The pair sorting policy takes precedence over the distance, point put after int n, m; void ini () {memset (vis, 0, sizeof (vis); // start all points are not processed memset (head,-1, sizeof (head); // all vertices have no edge (Int I = 0; I <= n; I ++) dis [I] = INF; // The distance from the start point to all vertices is infinite} void dij (int s, int e) {priority_queue <pi> Q; // priority queue dis [s] = 0; Q. push (make_pair (dis [s], s); while (! Q. empty () {pi u = Q. top (); Q. pop (); // retrieve the smallest vertex of d, int x = u. second; if (x = e) break; if (vis [x]) // processed, skip continue; vis [x] = 1; for (int I = head [x]; ~ I; I = next [I]) // update the distance from the nearest vertex of the current d {if (dis [v [I]> dis [x] + w [I]) {dis [v [I] = dis [x] + w [I]; // fa [v [I] = x; Q. push (make_pair (dis [v [I], v [I]); // Add the updated vertex to the queue.} if (dis [e] = INF) return; // s to e without path vector <int> ans; // use the vector to find the path from the end point to the start point, or use the recursive int temp = e; while (temp! = S) {ans. push_back (temp); temp = fa [temp];} ans. push_back (s); for (int I = ans. size ()-1; I> = 0; I --) printf ("% d", ans [I]); printf ("\ n % d \ n ", dis [e]);} int main () {// freopen ("in.txt", "r", stdin); int t; scanf ("% d ", & t); while (t --) {scanf ("% d", & n, & m); ini (); for (int I = 0; I <m; I ++) {scanf ("% d", u + I, v + I, w + I ); next [I] = head [u [I]; head [u [I] = I; // create an adjacent table} int S, E; // start point scanf ("% d", & S, & E); dij (S, E) ;}return 0 ;}

Dijkstra has a classic comparison, but does not require negative weights. So I learned how to handle spfa with negative weights:

Spfa feels a bit like bfs, but bfs only processes one node once. If spfa relaxes the nodes passing through the path, it should update all the nodes following the path. If there is a negative ring, every time a negative ring is taken, the distance decreases the length of the ring, and there is no short circuit. Therefore, assume that there is no negative ring (or judge whether there is a negative ring ). The Code is as follows:

# Include <bits/stdc ++. h> // Directed Graph using namespace std; const int maxn = 1007, maxm = 10007, INF = 2147483467; int head [maxn], in [maxn], dis [maxn], fa [maxn]; // The vertex int u [maxm], v [maxm], w [maxm], next [maxm], int n, m in the queue; void ini () {memset (in, 0, sizeof (in); memset (head,-1, sizeof (head); for (int I = 0; I <= n; I ++) dis [I] = INF;} void print (int s, int e) // recursively print the path {if (e! = S) print (s, fa [e]); printf ("% d", e);} void spfa (int s, int e) // a bit like bfs, however, bfs does not process the previously processed vertex {queue <int> Q; dis [s] = 0; in [s] = 1; Q. push (s); while (! Q. empty () {int x = Q. front (); Q. pop (); in [x] = 0; for (int I = head [x]; ~ I; I = next [I]) {if (dis [v [I]> dis [x] + w [I]) {dis [v [I] = dis [x] + w [I]; fa [v [I] = x; if (! In [v [I]) {Q. push (v [I]); in [v [I] = 1 ;}}} print (s, e); printf ("\ n % d \ n ", dis [e]);} int main () {freopen ("in.txt", "r", stdin); int t; scanf ("% d", & t ); while (t --) {scanf ("% d", & n, & m); ini (); for (int I = 0; I <m; I ++) {scanf ("% d", u + I, v + I, w + I ); next [I] = head [u [I]; head [u [I] = I;} int s, e; scanf ("% d ", & s, & e); spfa (s, e) ;}return 0 ;}

The multi-source shortest path has a floyd algorithm, which is actually the warshall closure in Discrete mode: (however, due to time complexity, O (n ^ 3) is a bit too much than 2333). The core code is as follows:

    for(int k = 1; k <= n; k++)        for(int i = 1; i <= n; i++)            for(int j = 1; j <= n; j++)                if(g[i][j] > g[i][k] + g[k][j])                    g[i][j] = g[i][k] + g[k][j];

The idea is to start to store graphs using an adjacent matrix. Updating the distance between two points can only be transited by another point. Therefore, each time you are allowed to go through one point (that is, the first loop ), consider the shortest path (the second triplicate loop ).

The advantage of floyd is that the Code is short and the shortest path between all nodes can be obtained at a time.

 

Today, we have gained a lot. To sum up, we use dijkstra for dense/non-negative weight graphs and spfa for sparse/negative weight graphs. floyd is not highly time-required.

 

 

 

(Bad mood)

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.