Single source shortest path template SPFA

Title Description

For example, if a directed graph is given, please output the shortest path length from a point to all points.

I / O format

Input format:
The first line contains three integers N, M and S, which respectively represent the number of points, the number of directed edges and the number of starting points.

Next, each row of row M contains three integers Fi, Gi and Wi, which respectively represent the starting point, target point and length of the i-th directed edge.

Output format:
One line, containing N integers separated by spaces, where the i-th integer represents the shortest path length from point S to point I (if S=i, the shortest path length is 0; if from point S cannot reach point I, the shortest path length is 2147483647)

Data size:

For 20% data: n < = 5, m < = 15

For 40% of data: n < = 100, m < = 10000

For 70% of data: n < = 1000, m < = 100000

For 100% data: n < = 10000, m < = 500000
Because we can see from the data scale that it is obviously not possible to use adjacency matrix to store graphs, so we use adjacency table to store graphs.

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
struct I {
    int to,next,val;
} edge[500005];
int head[500005];
int que[500005];
int cnt,s,n,m;
void add(int bg,int ed,int v) {//Adjacency table is stored.
    edge[++cnt].to=ed;
    edge[cnt].val=v;
    edge[cnt].next=head[bg];
    head[bg]=cnt;
}
int dis[500005];
bool vis[500005];
void spfa() {
    int u,l=0,r=1;
    que[1]=s;//Initialization of spfa
    vis[s]=1;
    dis[s]=0;
    while(l<r){
        u=que[++l];
        vis[u]=0;
        for(int i=head[u];i!=-1;i=edge[i].next){
            if(dis[edge[i].to]>dis[u]+edge[i].val){//If the shortest distance of the next point of this point is greater than the shortest path of the point pointed to by the head pointer plus the distance between them, the update will occur.
                dis[edge[i].to]=dis[u]+edge[i].val;
                if(!vis[edge[i].to]){//Avoid double entry.
                    vis[edge[i].to]=1;
                    que[++r]=edge[i].to;
                }
            }
        }
    }
}
int main() {
    memset(dis,0x3f,sizeof dis);
    memset(head,-1,sizeof head);
    cin>>n>>m>>s;
    for(int i=1; i<=m; i++) {
        int a,b,c;
        scanf("%d%d%d",&a,&b,&c);
        add(a,b,c);
    }spfa();
    for(int i=1;i<=n;i++){
        if(i==s)cout<<0<<" ";
        else {
            if(dis[i]==0x3f3f3f3f)cout<<2147483647<<" ";
            else cout<<dis[i]<<" ";
        }
    }
}

SPFA is actually the optimization of Bellman Ford's algorithm, adding a queue. If this point has been updated before, then it is possible for it to update other points (because if it has not been updated, it means that the current storage number of this point is the shortest at present, and it is unable to update the points connected with it.)

Posted by tazgalsinh on Fri, 01 May 2020 20:58:18 -0700