最短路径算法模板:Dijkstra/Floyd/Bellman-Ford模板

此处不解释算法,只写代码模板。

Dijkstra

邻接矩阵实现

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
const int MAX=0x3f3f3f3f;
int map[110][110];
int dis[110];
int visit[110];
/*
关于三个数组:map数组存的为点边的信息,比如map[1][2]=3,表示1号点和2号点的距离为3
dis数组存的为起始点与每个点的最短距离,比如dis[3]=5,表示起始点与3号点最短距离为5
visit数组存的为0或者1,1表示已经走过这个点。
*/
int n,m;
int dijkstra()
{
    int i,j,pos=1,min,sum=0;
    memset(visit,0,sizeof(visit));//初始化为0,表示开始都没走过
    for(i=1; i<=n; i++)
    {
        dis[i]=map[1][i];
    }
    visit[1]=1;
    dis[1]=0;
    int T=n-1;
    while(T--)
    {
        min=MAX;
        for(j=1; j<=n; j++)
        {
            if(visit[j]==0&&min>dis[j])
            {
                min=dis[j];
                pos=j;
            }
        }
        visit[pos]=1;//表示这个点已经走过
        for(j=1; j<=n; j++)
        {
            if(visit[j]==0&&dis[j]>min+map[pos][j])//更新dis的值
                dis[j]=map[pos][j]+min;
        }
    }
    return dis[n];
}
int main()
{
    int i,j;
    while(cin>>n>>m)//n表示n个点,m表示m条边
    {
        memset(map,MAX,sizeof(map));
        int a,b,c;
        for(i=1; i<=m; i++)
        {
            cin>>a>>b>>c;
            if(c<map[a][b])//防止有重边
                map[a][b]=map[b][a]=c;
        }
        int sum=dijkstra();
        cout<<sum<<endl;
    }
    return 0;
}

vector邻接表实现

#include <stdio.h>
#include <string.h>
#include <string>
#include <vector>
#include <algorithm>
#define INF 0x3f3f3f3f

using namespace std;

struct node
{
    int end;//终点
    int power;//权值
} t;

int n;//n为边数
vector<node>q[500001];//邻接表存储图的信息
int dis[500001];//距离数组
bool vis[500001];//标记数组

void Dijkstra(int start, int end)
{
    memset(vis, false, sizeof(vis));
    for(int i=0; i<=n; i++)
    {
        dis[i] = INF;
    }
    int len=q[start].size();
    for(int i=0; i<len; i++)
    {
        if(q[start][i].power < dis[q[start][i].end] )
            dis[q[start][i].end]=q[start][i].power; //从起点开始的dis数组更新
    }

    vis[start]=true;//起点标记为1

    for(int k=0; k<n-1; k++)
    {
        int pos, min=INF;
        for(int i=1; i<=n; i++)
        {
            if( !vis[i] && dis[i]<min )
            {
                //当前节点未被访问过且权值较小
                min=dis[i];
                pos=i;
            }
        }

        vis[pos]=true;

        //再次更新dis数组
        len=q[pos].size();
        for(int j=0; j<len; j++)
        {
            if( !vis[q[pos][j].end] && dis[ q[pos][j].end ]>q[pos][j].power+dis[pos] )
                dis[q[pos][j].end ] = q[pos][j].power + dis[pos];
        }
    }
    printf("%d\n", dis[end] );
}


int main()
{
    int m;
    while(scanf("%d %d", &n, &m)&&n&&m)//输入点和边
    {
        for(int i=0; i<=n; i++)
            q[i].clear();//将vector数组清空
        for(int i=0; i<m; i++)
        {
            int begin,end, power;
            scanf("%d %d %d", &begin, &end, &power);//输入
            /*t作为node型临时变量,为了方便压入,以下代码为无向图的输入边*/
            t.end=end;
            t.power=power;
            q[begin].push_back(t);
            t.end=begin;
            t.power=power;
            q[end].push_back(t);
        }
        //Dijkstra(1, n);
        int start, end;//自己确定起始点和终止点
        scanf("%d %d", &start, &end);//输入起始点和终止点
        Dijkstra(start, end);
    }
    return 0;
}

Floyd

#include<iostream>
#include <cstdio>
#include<cstring>
using namespace std;
const int MAX=0x3f3f3f3f;
int map[1100][1100];
void floyd(int n)
{
    for(int k=1; k<=n; k++)
        for(int i=1; i<=n; i++)
            for(int j=1; j<=n; j++)
                map[i][j]=min(map[i][j],map[i][k]+map[k][j]);  //这里用了min函数,可能会多一点耗时。
}
int main()
{
    int i,j,n,m;    //读入n和m,n表示顶点个数,m表示边的条数
    cin>>n>>m;
    memset(map,MAX,sizeof(map));  //初始化
    for(i=1; i<=n; i++)
        for(j=1; j<=n; j++)
            if(i==j)
                map[i][j]=0;
    int a,b,c;
    for(i=1; i<=m; i++)
    {
        cin>>a>>b>>c;
        map[a][b]=c;//这是一个有向图
    }
    floyd(n);
    for(i=1; i<=n; i++)
    {
        for(j=1; j<=n; j++)
        {
            cout<<map[i][j]<<" ";
        }
        cout<<endl;
    }
    return 0;
}

Bellman-Ford

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
const int MAX=0x3f3f3f3f;
const int N=1010;
int nodenum, edgenum, source; //点,边,起点
typedef struct Edge
{
    int st;
    int ed;
    int power;
} Edge;
Edge edge[N];
int dis[N];
void inite()  //初始化图
{
    cin>>nodenum>>edgenum>>source;
    memset(dis,MAX,sizeof(dis));
    dis[source]=0;
    for(int i=1; i<=edgenum; i++)
    {
        cin>>edge[i].st>>edge[i].ed>>edge[i].power;
        if(edge[i].st == source)          //注意这里设置初始情况
            dis[edge[i].ed] = edge[i].power;
    }
}
void relax(int st,int ed,int power)  //松弛计算
{
    if(dis[ed]>dis[st]+power)
        dis[ed]=dis[st]+power;
}
bool Bellman_Ford()
{
    for(int i = 1; i <= nodenum - 1; i++)
        for(int j = 1; j <= edgenum; j++)
            relax(edge[j].st,edge[j].ed,edge[j].power);
    for(int i = 1; i <= edgenum; ++i)
    {
        if(dis[edge[i].ed] > dis[edge[i].st] + edge[i].power)
        {
            return 0;
        }
    }
    return 1;
}
int main()
{
    inite();
    if(Bellman_Ford())//如果没有负权
    {
        for(int i = 1; i <= nodenum; ++i) //每个点最短路
        {
            cout<<dis[i]<<" ";
        }
        cout<<endl;
    }
    return 0;
}




SPFA

poj 2387

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<string>
#include<cmath>
#include<iomanip>
#include<map>
#include<stack>
#include<vector>
#include<queue>
#include<set>
#include<utility>
#include<algorithm>
#define max(a,b)   (a>b?a:b)
#define min(a,b)   (a<b?a:b)
#define swap(a,b)  (a=a+b,b=a-b,a=a-b)
//#define memset(a)  memset(a,0,sizeof(a))
#define X (sqrt(5)+1)/2.0  //Wythoff
#define Pi acos(-1)
#define e  2.718281828459045
using namespace std;
typedef long long int LL;
typedef pair<int,int>pa;
const int MAXL(1e3);
const int INF(0x3f3f3f3f);
const int mod(1e9+7);
int dir[4][2]= {{-1,0},{1,0},{0,1},{0,-1}};
vector<pa>v[MAXL+50];
int vis[MAXL+50];
int dis[MAXL+50];
int SPFA(int s,int n)
{
    queue<int>q;
    memset(dis,INF,sizeof(dis));
    memset(vis,0,sizeof(vis));
    dis[s]=0;
    vis[s]=1;
    q.push(s);
    while(!q.empty())
    {
        int u=q.front();
        q.pop();
        vis[u]=0;
        for(int i=0;i<v[u].size();i++)
        {
            int x=v[u][i].first,y=v[u][i].second;
            if(dis[u]+y<dis[x])
            {
                dis[x]=dis[u]+y;
                if(!vis[x])
                {
                    q.push(x);
                    vis[x]=1;
                }
            }
        }
    }
    return dis[n];
}
int main()
{
    int T,n;
    cin>>T>>n;
    for(int i=1;i<=T;i++)
    {
        int x,y,z;
        cin>>x>>y>>z;
        pa p;
        p=make_pair(y,z);
        v[x].push_back(p);
        p=make_pair(x,z);
        v[y].push_back(p);
    }
    int ans=SPFA(1,n);
    cout<<ans<<endl;
}
    原文作者:Bellman - ford算法
    原文地址: https://blog.csdn.net/Akatsuki__Itachi/article/details/76082494
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞