ACM: the short circuit, Dijkstra, and the establishment of the adjacent table. Use the Dijkstra, Bellman-Ford, and Floyd of the adjacent table and the priority queue ..

Source: Internet
Author: User

(1) Dijkstra, adjacent matrix

All edge weights are positive, no matter whether there is a ring, find the shortest path from a single source point to all nodes. This method is applicable to Directed Graphs and undirected graphs.

# Include <iostream> # include <string> # include <stack> using namespace STD; const int maxn = 1000; const int INF = 100000000; int n, m; int maze [maxn] [maxn], vis [maxn], d [maxn], Fa [maxn]; // d [I] indicates the stack distance from node I to source point 0 <int> S; void print_path1 (Int J) {If (j = 0) return; S. push (j); While (j) {for (INT I = 0; I <n; ++ I) {If (d [J] = d [I] + maze [I] [J]) {S. push (I); j = I; break ;}} cout <S. top (); S. pop (); While (! S. empty () {cout <"->" <S. top (); S. pop () ;}cout <Endl;} void print_path2 (Int J) {If (j = 0) return; while (j) {S. push (j); j = Fa [J];} s. push (j); cout <S. top (); S. pop (); While (! S. empty () {cout <"->" <S. top (); S. pop () ;}cout <Endl ;}int main () {freopen ("E: // data.txt", "r", stdin ); cin> N> m; For (INT I = 0; I <n; ++ I) {for (Int J = 0; j <n; ++ J) {maze [I] [J] = inf ;}for (INT I = 0; I <m; ++ I) {int U, V, W; cin> U> V> W; maze [u] [v] = maze [v] [u] = W;} memset (VIS, 0, sizeof (VIS); For (INT I = 0; I <n; ++ I) d [I] = (I = 0? 0: INF); // initialize the D array for (INT I = 0; I <n; ++ I) {// loop N times int M = inf, X; for (INT y = 0; y <n; ++ y) {// select the node xif (! Vis [y] & D [y] <= m) M = d [x = y];} vis [x] = 1; for (INT y = 0; Y <n; ++ y) {// For all edges (x, y) starting from X, update d [y] = min (d [Y], d [x] + maze [x] [Y]) if (d [y]> d [x] + maze [x] [Y]) {d [y] = d [x] + maze [x] [Y]; Fa [y] = X; // maintain the parent pointer }}for (INT I = 0; I <n; ++ I) {cout <D [I] <Endl; print_path1 (I ); // print the path. Method 1: Start from the end and keep following the edge of d [J] = d [I] + maze [I] [J] (I, j) return from node J to node I until return to the start point. Print_path2 (I); // print Path Method 2: Change the space time! Maintain the parent pointer when updating the D array !} Return 0 ;}

(2) establish an adjacent table

An adjacent table can be used for Directed Graphs or undirected graphs. In this representation, each node I has a linked list, which stores all the edges starting from I. For an undirected graph, each edge appears twice in the adjacent table.

Here we use arrays to implement the linked list: first number each edge, and then use first [u] To save the number of the first edge of node u, next [e] indicates the number of the "next edge" of an edge numbered E.

The following code creates an adjacent table for a directed graph.

#include <iostream>using namespace std;const int MAXN = 1000;int first[MAXN], next[MAXN], u[MAXN], v[MAXN], w[MAXN];int main() {int n, m;cin >> n >> m;for(int i = 0; i < n; ++i) first[i] = -1; for(int e = 0; e < m; ++e) {cin >> u[e] >> v[e] >> w[e];next[e] = first[u[e]];first[u[e]] = e;}for(int i = 0; i < n; ++i) cout << first[i] << endl;for(int e = 0; e < m; ++e) cout << next[e] << endl;return 0;}
The clever solution of the above Code is to insert it into the head of the linked list instead of the tail, thus avoiding the traversal of the linked list. Here, the order of each edge at the same starting point in the adjacent table is exactly the opposite of the read order.

(3) Use the Dijkstra of the adjacent table and the priority queue.

The only difference between queue and priority_queue is that in the priority queue, elements are not arranged in the order of entering the queue, but in the order of priority. Pop () deletes the element with the highest priority, not necessarily the element that first enters the queue. Therefore, the method for getting the first element is no longer front (), but top ().

Struct CMP {bool operator () (const int A, const int B) {// the priority of a returns truereturn a % 10> B % 10;} compared to B hour ;}}; priority_queue <int, vector <int>, CMP> q; // an integer priority queue with a single-digit priority rather than a small value


Declare the priority queue of a small integer first-out queue:

priority_queue< int, vector<int>, greater<int> > q;

In the Dijkstra algorithm, not only do we need to find the smallest d [I], but we need to play it out from the priority queue together with the node number, so we use pair

For convenience, we use typedef pair <int, int> PII to customize a PII type, then priority_queue <PII, vector <PII>, greater <PII> q defines a priority queue consisting of binary groups!

Pair defines its own sorting rules-compare the first dimension to compare the second dimension when they are equal. Therefore, you need to press (d [I], I) instead of (I, d [I!


The code for implementing the Dijkstra algorithm using the adjacent table + binary heap is as follows:

# Include <iostream> # include <queue> using namespace STD; const int maxn = 1000; const int maxm = 100000; const int INF = 100000000; int n, m; int first [maxn], d [maxn], done [maxn]; // when searching for the point X closest to the source point, done [I] indicates that the I node has been processed by INT U [maxm], V [maxm], W [maxm], next [maxm]; typedef pair <int, int> PII; int main () {CIN> N> m; For (INT I = 0; I <n; I ++) first [I] =-1; // initialize the header of the adjacent table for (int e = 0; e <m; ++ e) {// establish CIN of the adjacent table> U [e]> V [e]> W [E]; next [e] = first [U [e]; first [U [e] = E;} priority_queue <PII, vector <PII>, greater <PII> q; // used in all unprocessed nodes, select the node xmemset (done, 0, sizeof (done) with the smallest D value. // assume that all nodes have not been processed. push (make_pair (d [0], 0); // start point to enter the priority queue for (INT I = 0; I <n; ++ I) d [I] = (I = 0? 0: INF); While (! Q. empty () {PII u = Q. top (); q. pop (); int x = u. second; // X indicates the node with the smallest D value if (done [x]) continue; // it has been calculated, ignoring done [x] = 1; for (int e = first [X]; e! =-1; E = next [e]) {// traverse all edges starting from x (x, y) update d [y] If (d [V [e]> d [x] + W [e]) {d [V [e] = d [x] + W [E]; // relaxed successfully. Update d [V [e] Q. push (make_pair (d [V [e], V [e]) ;}}for (INT I = 0; I <n; ++ I) cout <D [I] <Endl; return 0 ;}

(4) Bellman-Ford Algorithm

When there is a negative weight in the figure, the shortest path may not exist, but it can still be obtained when the shortest path exists.

If the shortest path exists, the shortest path must not contain loops!

Cause: three factors are considered: positive ring, zero ring, and negative ring!

If it is a positive or zero ring, the shortest path will definitely not pass through it! If it is a negative ring, there must be no short circuit!

Since the shortest path does not contain loops, the shortest path can only pass through n-1 nodes at most (not counted from the start point), so we can get it through n-1 series of relaxation operations!

# Include <iostream> using namespace STD; const int maxn = 1000; const int INF = 100000000; int n, m; int d [maxn], U [maxn], V [maxn], W [maxn]; int main () {CIN> N> m; For (int e = 0; e <m; ++ E) {CIN> U [e]> V [e]> W [e] ;}for (INT I = 0; I <n; ++ I) d [I] = inf; d [0] = 0; For (int K = 0; k <n-1; ++ K) {// iterations n-1 for (int e = 0; e <m; ++ e) {// check each edge int x = U [E]; int y = V [E]; If (d [x] <inf) d [y] = min (d [Y], d [x] + W [e]); // relaxation operation }}for (INT I = 0; I <n; ++ I) cout <D [I] <Endl; return 0 ;}


The queue is more efficient, as shown in the following code:

# Include <iostream> # include <string> # include <queue> using namespace STD; const int INF = 1000000000; const int maxn = 1000; const int maxm = 100000; int N, m; int first [maxn], d [maxn]; int U [maxm], V [maxm], W [maxm], next [maxm]; int main () {CIN> N> m; For (INT I = 0; I <n; ++ I) First [I] =-1; for (int e = 0; E <m; ++ e) {CIN> U [e]> V [e]> W [E]; next [e] = first [U [e]; first [U [e] = E;} queue <int> q; int INQ [ Maxn]; for (INT I = 0; I <n; ++ I) d [I] = (I = 0? 0: INF); memset (INQ, 0, sizeof (INQ); q. Push (0); While (! Q. empty () {int x = Q. front (); q. pop (); INQ [x] = 0; // mark that X is not in the queue for (int e = first [X]; e! =-1; E = next [e]) if (d [V [e]> d [x] + W [e]) {d [V [e] = d [x] + W [E]; If (! INQ [V [e]) {// If vertex v [e] is not in the queue, INQ [V [e] = 1; // mark point V [e] in the queue Q. push (V [e]) ;}}for (INT I = 0; I <n; I ++) cout <D [I] <Endl; return 0 ;}

(5) Floyd algorithm

If the minimum short circuit between every two points is required:

#include <iostream>using namespace std;const int MAXN = 1000;const int INF = 1000000;int d[MAXN][MAXN];int n;int main() {cin >> n;for(int i = 0; i < n; ++i) {for(int j = 0; j < n; ++j) {if(i == j) d[i][j] = 0;else d[i][j] = INF;}}for(int k = 0; k < n; ++k) {for(int i = 0; i < n; ++i) {for(int j = 0; j < n; ++j) {if(d[i][j] < INF && d[k][j] < INF) d[i][j] = min(d[i][j], d[i][k]+d[k][j]);}}}for(int i = 0; i < n; ++i) {for(int j = 0; j < n; ++j) {cout << d[i][j] << endl;}}return 0;}


















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.