Single-source Shortest path: Bellman-ford algorithm and SPFA algorithm __ graph theory

Source: Internet
Author: User

The Dijkstra algorithm of Single-source Shortest path and the Floyd algorithm of the shortest path between any two points are discussed, and today we look at two other common algorithms for finding the shortest path of single source: Bellman-ford algorithm and SPFA algorithm. As for why we put these two together, the comparison SPFA algorithm is the improvement and optimization of the Bellman-ford algorithm.

Let's take a look at the Bellman-ford algorithm: In fact, Bellman-ford algorithm and Dijkstra algorithm are similar, the reason for the proposed Bellman-ford algorithm, is to solve the problem of the shortest path with a negative weight value. Bellman-ford algorithm is very inefficient, he is through the continuous relaxation of each side, so as to update the source point to the shortest distance to each point; for a graph with n vertices, the relaxation operation of the Bellman-ford algorithm needs to be n-1 over, Each relaxation will be accompanied by the shortest distance updates, if the n-1 after relaxation can also update the shortest distance, then there is a negative weight in the diagram of the loop (take a triangle of the negative weight of the loop, the picture can be understood).

The algorithm flow of the Bellman-ford algorithm is as follows:

(1) Initialization: The distance array dis is initialized to the source point of the weight value (can also be initialized to +∞), and then updated to the source point dis is 0;

(2) Relaxation of the update operation: n-1 all over the relaxation (n is the number of vertices in the graph), each slack update all the edges;

(3) The negative ring: if the relaxation operation after a certain edge can still be updated, then it shows that there is a negative weight loop in the diagram.

The implementation code is as follows:

#include <iostream> #include <cstdio> #include <cstring> using namespace std; #define INF 999999999 #define MAX 1000 typedef struct Node {int u,v,w;}
EDGE;
EDGE Edge[max];
int Dis[max],pre[max];
int N,m_edge;
    void Add (int u,int v,int W) {m_edge++;
    Edge[m_edge].u=u;
    Edge[m_edge].v=v;
Edge[m_edge].w=w;
    BOOL Bellman_ford () {for (int i=0;i<=n;i++) Dis[i]=inf;
    dis[1]=0;
        for (int i=0;i<n;i++) for (int j=1;j<=m_edge;j++) if (DIS[EDGE[J].V]&GT;DIS[EDGE[J].U]+EDGE[J].W)
            {DIS[EDGE[J].V]=DIS[EDGE[J].U]+EDGE[J].W;
        pre[edge[j].v]=edge[j].u;
    BOOL Flag=true;
          for (int i=1;i<=m_edge;i++) if (DIS[EDGE[I].V]&GT;DIS[EDGE[I].U]+EDGE[I].W) {flag=false;
      Break
return flag;
        } void Print_path (int x) {while (x!=pre[x]) {printf ("%d-->", X);
    X=PRE[X];
} if (x==pre[x)) printf ("%d\n", X); int main () {
    int m;
    int u,v,w;
    m_edge=0;
        for (int i=0;i<m;i++) {scanf ("%d%d%d", &u,&v,&w);
    Add (u,v,w);//direction diagram Add (v,u,w);
          } if (Bellman_ford ()) for (int i=0;i<n;i++)//source point to the shortest path to each point {printf ("%d\n", Dis[i]);
          printf ("Path:");
      Print_path (i);
    else printf ("There is a negative weight loop \ n");
return 0; }




Next we look at the SPFA algorithm:

SPFA (shortest Path faster algorithm) is a queue optimization for the Bellman-ford algorithm. The algorithm is generally used in a queue to maintain the n vertices in the graph, the initial source point to join the queue, each time from the queue to take an element, and all adjacent to the point of the relaxation update, after the update of the team, in this process, if a certain point update, put this point into the queue, until the elements in the queues are 0, The algorithm ends.

The SPFA algorithm can find the shortest path of the source point to other points in the time complexity of O (KE), can handle the negative weight edge, some cases are even more effective than the Dijkstra algorithm, but the stability is inferior to the Dijkstra algorithm.

The algorithm flow is as follows:

(1) Initialization: The source point to each point of the distance dis initialized to +∞, the tag array vis initialized to false, indicating that all the points are not team; update the source point of dis 0, at the same time the source point team, change Vis to true;

(2) Relaxation Update operation: Every time the team HEAD element tmp (UPDATE vis[TMP] is false), enumerates each edge from TMP, and if an edge is slack and the point is not in the queue, the point is queued until the queue is empty;

(3) to the negative ring: If the number of points in the graph more than N, then there are negative loops (SPFA can not handle the problem with negative loops).

The implementation code, like the BFS, is somewhat similar to the following:


Adjacency Matrix Implementation Code:

The int  n,m;//n represents the number of vertices, m represents the number of edges
int w[max][max];//The adjacency matrix of the graph
int dis[max];//source point to the shortest path
bool vis[max];//tag Array
void Spfa ()
{for
    (int i=0;i<n;i++)
    {
        dis[i]=inf;
        Vis[i]=false;
    }
    Queue<int> que;
    Que.push (start);
    dis[start]=0;
    Vis[start]=true;
    while (!que.empty ())
    {
        int tmp=que.front ();
        Que.pop ();
        Vis[tmp]=false;
        for (int i=0;i<n;i++)
          if (Dis[i]>dis[tmp]+w[tmp][i])
          {
              dis[i]=dis[tmp]+w[tmp][i];
              if (!vis[i])
              {
                  Que.push (i);
                  Vis[i]=true}}}}




In the case of a larger number of edges and vertices in the graph, the adjacency matrix is obviously unable to meet our requirements, where the vector container is used to load the adjacent edge of a vertex, the code is as follows:

#include <cstdio> #include <iostream> #include <queue> #include <vector> using namespace std;
#define INF 0x7fffffff #define MAX 100005 struct Edge {int to,w;};
int Dis[max];
BOOL Vis[max];
int n,m,start,e;
Vector <edge> Vec[max];
        void Spfa () {for (int i=1;i<=n;i++) {dis[i]=inf;
    Vis[i]=false;
    } dis[start]=0;
    Queue<int> que;
    Que.push (start);
    Vis[start]=true;
        while (!que.empty ()) {int Tmp=que.front ();
        Que.pop ();
        Vis[tmp]=false;
            for (int i=0;i<vec[tmp].size (); i++) {Edge cnt=vec[tmp][i];
                if (dis[cnt.to]>dis[tmp]+cnt.w) {dis[cnt.to]=dis[tmp]+cnt.w;
                    if (!vis[cnt.to]) {Que.push (cnt.to);
                vis[cnt.to]=true;
    [}}}} int main () {cin>>n>>m>>start>>e; For(int i=0;i<=n;i++) vec[i].clear ();
        for (int i=1;i<=m;i++) {edge cnt1,cnt2;
        int u,v,w;
        scanf ("%d%d%d", &u,&v,&w);
        Cnt1.to=u;cnt1.w=w;
        Cnt2.to=v;cnt2.w=w;
        Vec[u].push_back (Cnt2);
    Vec[v].push_back (CNT1);
    } SPFA ();
    cout<<dis[e]<<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.