Limitations of the 1.Dijkstra algorithm
Like, if you use the Dijkstra algorithm, it will be wrong, because if starting from 1, the first step dist[2] = 7, dist[3] = 5; in which the smallest edge is dist[3] = 5; then update dist[2] = 0, and finally dist[2] = 0,dist[3] = 5, while actually dist[3] = 2; So if the figure contains a negative weight, Dijkstra fails
2.bellman-ford algorithm Idea
Applicable premise: There is no negative ring (or negative weight value loop), because there is negative distance is negative infinity.
Constructs a shortest path length array sequence dist1[u] dist2[u]...distn-1[u], where:
Dist1[u] is the shortest path length of only one edge from the source point V0 to the end of U, and dist1[u] = Edge[v0][u]
Dist2[u] The shortest path length from the source point v0 up to two edges to the end point of the negative weight loop
Dist3[u] The shortest path length from the source point v0 up to three edges to the end point of the negative weight loop
................
Distn-1[u] The shortest path length from the source point v0 up to the n-1 edge to the end point of the non-negative weight loop
The ultimate goal of the algorithm is to calculate the Distn-1[u], which is the shortest path length of the source point to the vertex u
Initial: Dist1[u] = Edge[v0][u]
Recursive: distk[u] = min (Distk-1[u], min{distk-1[j] + Edge[j][u]}) (Slack operation, iteration n-2 times)
3. Essence of thought:
In the distk-1[u] recursion to distk[u], the essence of Bellman-ford algorithm is to each side <u, v> to judge: Set Edge <u, v> the weight of W (U, v), if the side <u, v> The introduction of the DISTK-1[V] will reduce the value, it is necessary to modify DISTK-1[V], that is: if Distk-1[u] + w (u, v) < Distk-1[v], then distk[v] = Distk-1[u] + w (u, v), This is called a relaxation.
So the recursive formula can be changed to:
Initial: Dist0[u] = INF Dist0[v0] = 0 (V0 is the source point)
Recursion: For Each edge (U, v) distk[v] = min (Distk-1[v], Distk-1[u] + w (u, v)) (slack operation, iterative n-1 times)
If the iteration is n-1, the iteration is repeated, and if there are dist at this time, the negative ring is present.
When there is no negative loop, the number of iterations is updated up to n-1 times, so setting an update variable can jump out of the loop without updating
Expand:
The Bellman-ford algorithm can also be used to find the longest road, the idea is that the dist array meaning is the length of the longest path from the origin to each other vertex, at the beginning, each vertex dist is 0, when from Distk-1[u] recursion to Distk[u], Bellman-ford algorithm is the essence of each side <u, v> to judge: Set the edge of <u, v> the weight of W (U, v), if the edge <u, the introduction of v> will make the value of distk-1[v] to increase, it is necessary to modify distk-1[ V], i.e.: if Distk-1[u] + w (u, v) > Distk-1[v], then distk[v] = Distk-1[u] + w (u, v)
4. Code implementation:
Input:
7 10
0 1 6
0 2 5
0 3 5
1 4-1
2 1-2
2 4 1
3 2-2
3 5-1
4 6 3
5 6 3
Output:
Distance from 0 to 1 is: 1 0->3->2->1
Distance from 0 to 2 is: 3 0->3->2
Distance from 0 to 3 is: 5 0->3
Distance from 0 to 4 is: 0 0->3->2->1->4
Distance from 0 to 5 is: 4 0->3->5
Distance from 0 to 6 is: 3 0->3->2->1->4->6
There is no negative ring
1#include <iostream>2#include <cstdio>3#include <cstring>4#include <algorithm>5#include <cmath>6#include <queue>7#include <stack>8#include <map>9#include <sstream>Ten using namespacestd; OnetypedefLong Longll; A Const intMAXN = ++Ten; - Const intINF =1<< -; - intT, N, m, cases; the structEdge - { - intu, V, W; - }; + Edge A[MAXN]; - intPATH[MAXN], D[MAXN]; + BOOLBellman (intv0) A { at for(inti =0; I < n; i++) D[i] = INF, path[i] =-1; -D[v0] =0; - for(inti =0; I < n; i++)//iterative n times, if the nth time is still updated, indicating a negative ring - { - BOOLUpdate =0; - for(intj =0; J < M; J + +) in { - intx = a[j].u, y =a[j].v; to //cout<<x<< "" <<y<< "" <<a[j].w<<endl; + if(D[x] < INF && D[x] + A[J].W <D[y]) - { theD[y] = D[x] +A[J].W; *Path[y] =x; $Update =1;Panax Notoginseng if(i = = N-1)//description nth time is still being updated - { the return true;//back true, there really is a negative ring + } A } the } + if(!update) Break;//if it's not updated, it's already loose. - } $ for(inti =0; I < n; i++) $ { - if(i = = V0)Continue; -printf"The distance from%d to%d is:%2d", V0, I, D[i]); thestack<int>Q; - intx =i;Wuyi while(path[x]! =-1) the { - Q.push (x); Wux =Path[x]; - } Aboutcout<<V0; $ while(!q.empty ()) - { -cout<<" -"<<q.top (); - Q.pop (); A } +cout<<Endl; the } - return false; $ } the intMain () the { theCIN >> N >>m; the for(inti =0; I < m; i++) Cin >> a[i].u >> a[i].v >>A[I].W; - if(Bellman (0)) cout<<"there is a negative ring"<<Endl; in Elsecout<<"there is no negative ring"<<Endl; the return 0; the}
Single Source Shortest path---bellman-ford algorithm