This chapter mainly describes:
1.Floyd-warshall algorithm : To solve the shortest distance between any two points, the time complexity of O (n^3).
(1) The use of conditions & scope: Usually can be used in any diagram, including a direction graph, with negative right side of the graph.
(2) Freud (Floyd) algorithm process:
1, with D[V][W] record the shortest distance of each pair of vertices.
2, scan each point in turn, and then iterate through all the values of each pair of vertex d[][] to see if the base points can be used to make the distance between the vertices smaller.
(3) The code is implemented as follows:
#include <iostream> #include <string> #include <stdio.h> using namespace std;
#define MAXVERTEXNUM #define INF 99999/*** Floyd * * typedef struct {char vertex[maxvertexnum];
int Edges[maxvertexnum][maxvertexnum];
int n, E;
}mgraph;
void Createmgraph (Mgraph &g) {int I, j, K, p;
cout << "Please enter the number of vertices and edges: \ n";
CIN >> G.N >> g.e;
cout << "Please enter vertex elements: \ n";
for (i = 0; i<g.n; i++) {cin >> g.vertex[i];
for (i = 0; i<g.n; i++) {for (j = 0; j<g.n; j + +) {G.edges[i][j] = INF;
if (i = = j) {G.edges[i][j] = 0;
}} for (k = 0; k<g.e; k++) {cout << "Please enter the" << K + 1 << "arc end serial number and corresponding weight: \ n";
Cin >> I >> j >> p;
G.EDGES[I][J] = p;
} void Dispath (int a[][maxvertexnum], int path[][maxvertexnum], int n);
void Floyd (Mgraph G) {int a[maxvertexnum][maxvertexnum], path[maxvertexnum][maxvertexnum];
int I, j, K; for (i = 0; i<g.n; i++) {foR (j = 0; j<g.n; j + +) {A[i][j] = g.edges[i][j];
PATH[I][J] =-1; for (k = 0; k<g.n; k++) {for (i = 0; i<g.n; i++) {for (j = 0; j<g.n; j + +) {if (a[i][j]> ;
A[I][K] + a[k][j]) {a[i][j] = A[i][k] + a[k][j];
PATH[I][J] = k;
}} dispath (A, Path, G.N);
} void Ppath (int path[][maxvertexnum], int i, int j) {int k;
k = Path[i][j];
if (k = = 1) {return;
} ppath (path, I, K);
printf ("%d,", k);
Ppath (Path, K, j);
} void Dispath (int a[][maxvertexnum], int path[][maxvertexnum], int n) {int i, J; for (i = 0; i<n; i++) {for (j = 0; j<n; j +) {if (a[i][j] = = INF) {if (I!= j) {printf ("
No path from%d to%d \ n ", I, j);
} else {printf ("from%d to%d=> path length:%d path: \ n", I, J, A[i][j]);
printf ("%d,", I);
Ppath (Path, I, j);
printf ("%d\n", j);
int main () {freopen ("Input.txt", "R", stdin);
Mgraph G;
Createmgraph (G);
Floyd (G);
return 0; }/** Floyd algorithmThe input is as follows: 4 8 A B C D 0 1 6 0 3 3 1 0 5 1 2 1 2 0 3 2 3-2 3 0 8 3/1 *
The results of the operation are as follows:
2.Johnson Algorithm (sparse graph): Find the shortest path between all node pairs in the time of O (v*v LGV + VE)
(1) The use of conditions & scope: usually can be used in any diagram, including a direction graph, with negative right side of the graph.
(2) Johnson algorithm Process:
The algorithm uses Dijskra, Bellmanford algorithm , the use of the technology is to re-assign weights ,
A. If the weights in Figure G = (V, E) are all non-negative, the shortest path of all node pairs is found by running a Dijkstra algorithm on all nodes.
B. If there is a non-negative value, but there is no negative weight of the loop, then just calculate a new set of nonnegative weight values, and then use the same method.
(3) The code is implemented as follows:
/************************************************************ Johnson.h:johnson algorithm, stored as adjacency table, ********************** /#include <vector> #include <queue> #include <stack> #inc
Lude <iostream> #include <algorithm> #include <functional> using namespace std; The structure of adjacency table struct Arcnode//table node {int source; The source node int Adjvex of the arc in the figure; The position of the vertex pointed to by the Arc Arcnode *nextarc; pointer int weight pointing to the next arc;
Weight of each edge}; Template <typename vertextype> struct Vertexnode//Header node {vertextype data; Vertex information Arcnode *firstarc; A pointer int key that points to the first arc attached to the vertex;
Prim: Holds the weight of the smallest edge in all the edges connected to the vertex and the nodes in the tree; Bellmanford: Record the upper bound Vertexnode *p of the shortest path weight from source node to the node; Point to the parent node int indegree in the tree;
Record the entry of each vertex};
const int SIZE = 6;
The operation of the diagram template <typename vertextype> class Algraph {public:typedef vertexnode<vertextype>; algraph (int vernum): VExnum (Vernum), Arcnum (0) {for (int i = 0; i < Max_vertex_num; i++) {vertices[i].firstarc = NULL;
Vertices[i].key = INT_MAX/2;
VERTICES[I].P = NULL;
Vertices[i].indegree = 0;
}//Construction algorithm Introduction 410 page diagram (with weighted forward graph) void Createwdg () {cout << "Construction algorithm Introduction 410 page diagram (with weighted direction diagram) ..." << Endl;
int i;
for (i = 1; i < vexnum i++) Vertices[i].data = ' a ' + i-1;
Insertarc (1, 2, 3);
Insertarc (1, 3, 8);
Insertarc (1, 5,-4);
Insertarc (2, 4, 1);
Insertarc (2, 5, 7);
Insertarc (3, 2, 4);
Insertarc (4, 3,-5);
Insertarc (4, 1, 2);
Insertarc (5, 4, 6);
} void Createg () {cout << "construct diagram G ' ..." << Endl;
Vertices[0].data = ' s ';
Insertarc (0, 1, 0);
Insertarc (0, 2, 0);
Insertarc (0, 3, 0);
Insertarc (0, 4, 0);
Insertarc (0, 5, 0); //johnson algorithm, first use the Bellmanford algorithm, make all the weights of the edges into non-negative,//And then use the Dijkstra algorithm to find the shortest path int **johnson () {Createg () of the node pair;
Tectonic G ' displaygraph (); if (! Bellmanford (1)) cout << "The input graph ContaINS a negative-weight cycle "<< Endl;
else {int h[size];
int I, j, K;
Set the value of the array h[] to the value obtained after running Bellmanford, H[i] is the shortest path for node s to other points for (i = 0; i < vexnum; i++) h[i] = Vertices[i].key;
Iterate over all the edges, reassign the weights of the edges, and change the weights of all the edges to negative for (i = 0; i < Vexnum; i++) {Arcnode *arc = Vertices[i].firstarc;
for (; Arc!= NULL; arc = arc->nextarc) Arc->weight = Arc->weight + H[arc->source]-h[arc->adjvex]; //The following code: cout << "After changing the weight of the figure is:" << Endl;
Displaygraph ();
int **d = new int *[size];
for (j = 0; J < SIZE; J +) D[j] = new Int[size];
Run Dijkstra algorithm for each node, find the shortest path of each point to other points, save in key for (k = 1; k < SIZE; k++) {Dijkstra (k + 1);
for (i = 1; i < SIZE; i++) D[k][i] = Vertices[i].key + h[i]-h[k];
cout << "The shortest distance of the last computed node pair:" << Endl;
Displaytwodimarray (d); return D; ///output a two-dimensional array void Displaytwodimarray (int **p) {for (int i = 0; i < SIZE; i++) {for (int j = 0; J < SIZE;
J + +) cout << p[i][j] << "";
cout << Endl;
} cout << "~~~~~~~~~~~~~~~" << Endl; }//print adjacency list virtual void Displaygraph () {for (int i = 0; i < Vexnum; i++) {cout << "I" << i +
1 << "vertex is:" << vertices[i].data << "vertex of the entry for:" << vertices[i].indegree << "adjacency table:";
Arcnode *arcnode = Vertices[i].firstarc; while (Arcnode!= NULL) {cout << "->" << vertices[arcnode->adjvex].data << "(" <
< Arcnode->weight << ")";
Arcnode = arcnode->nextarc;
} cout << Endl;
} cout << "*******************************************************" << Endl; //pvnode sort Criteria Class Pvnodecompare {Public:bool operator () (Vnode *pvnode1, Vnode *pvnode2) {return Pvnod E1->Key > pvnode2->key;
}
}; The shortest path estimation and the initial node of each node are initialized, the shortest path is initialized to Int_max, p is initialized to NULL//And the key of the source node is initialized to 0 void initalizesinglesource (int index) {for
(int i = 0; i < max_vertex_num; i++)
{Vertices[i].key = Int_max >> 2;
VERTICES[I].P = NULL;
} vertices[index].key = 0; //Pair Edge (U, v) slack, compare the shortest path of the current S to v V.key with the shortest path of s to U plus the value of W (U, v), and if it is larger than the later value, update to shorten the V.key and p to the U void Relax (Arcnode *a
RC) {//unexpectedly overflowed. if (Vertices[arc->adjvex].key > Vertices[arc->source].key + arc->weight) {Vertices[arc->adjvex].key =
Vertices[arc->source].key + arc->weight;
VERTICES[ARC->ADJVEX].P = &vertices[arc->source];
}//bellmanford, index is the actual first few points bool Bellmanford (int index) {initalizesinglesource (index-1); for (int i = 1; i < vexnum i++)//loops are vexnum-1 times {//traversal all edges, and a slack for each edge for (int j = 0; j < Vexnum; J + +) {for (Arcnode *arc = vertices[j].firstarc; arc!= NULL; arc = Arc->nextarc) Relax (ARC); }///traverse all edges again, check the diagram for loops with a negative weight and, if present, return FALSE for (int j = 0; J < Vexnum + +) {for (Arcnode *arc = Verti Ces[0].firstarc; Arc!= NULL;
Arc = Arc->nextarc) {if (Vertices[arc->adjvex].key > Vertices[arc->source].key + arc->weight)
return false;
}} cout << "Bellmanford Shortest path for single source:" << Endl;
for (int i = 1; i < Vexnum i++) {Printpath (index-1, i);
} cout << "**************************************************" << Endl;
return true;
} void Dijkstra (int index) {initalizesinglesource (index-1); Vector<vnode> Snode; Save the node that has found the shortest path vector<vnode *> que; An array that holds the pointer to the node, using this array to execute the heap's algorithm//the node pointer into the queue to form the minimum heap for key value (int i = 0; i < vexnum i++) Que.push_back (& ver
Tices[i]));
The que is composed of a minimum heap make_heap (Que.begin (), Que.end (), Pvnodecompare ()) According to the Pvnodecompare criterion; while (que.empty () = = False) {//Vnode the node with the smallest key in the queue out of the team *nodE = Que.front (); Pop_heap (Que.begin (), Que.end (), Pvnodecompare ()); Remove the smallest node from the heap, only to the last que.pop_back of the vector ();
Remove this node from the vector completely, because it will be sorted again, so as not to affect the subsequent heap ordering, pop algorithm.
Snode.push_back (*node);
for (Arcnode *arc = node->firstarc; arc!= NULL; arc = arc->nextarc) relax (ARC);
Make_heap (Que.begin (), Que.end (), Pvnodecompare ());
cout << "Dijkstra the shortest path to find the single source:" << Endl;
for (int i = 1; i < Vexnum i++) {if (I!= index-1) printpath (index-1, i);
} cout << "**************************************************" << Endl; Protected://Insert a table node void Insertarc (int vhead, int vtail, int weight) {//Construct a table node Arcnode *newarcnode = new
Arcnode;
Newarcnode->source = Vhead;
Newarcnode->adjvex = Vtail;
Newarcnode->nextarc = NULL;
Newarcnode->weight = weight;
Arcnode is the adjacency table of vertics[vhead] arcnode *arcnode = Vertices[vhead].firstarc; if (Arcnode = = NULL) Vertices[vhead].firstarc = NEWARCNOde
else {while (Arcnode->nextarc!= NULL) {Arcnode = arcnode->nextarc;
} Arcnode->nextarc = Newarcnode;
} arcnum++; vertices[vtail].indegree++; The entry of the tail node of the ARC plus 1}//Print source node to I shortest path void printpath (int i, int j) {cout << "from source node" << Vertices[i].data &
lt;< "To the destination node" << vertices[j].data << "The Shortest Path is:"/*<< endl*/;
__printpath (&vertices[i], &vertices[j]);
cout << "The weight is:" << vertices[j].key << Endl; } void __printpath (vnode* source, vnode* dest) {if (Source = dest) cout << source->data << "->
"; else if (dest->p = NULL) cout << no path.
"<< Endl;
else {__printpath (source, dest->p);
cout << dest->data << "->"; } Private://const data members must initialize the static const int max_vertex_num = 20 in the constructor; Maximum number of vertices vnode vertices[max_vertex_num]; The array int vexnum that holds the node; The current vertex number of the graph int ARCnum; Number of arcs in the graph};
int main ()
{
algraph<char> wdggraph (6);
WDGGRAPH.CREATEWDG ();
Wdggraph.johnson ();
/*wdggraph.displaygraph (); */
System ("pause");
return 0;
}
The results of the operation are as follows: