最短路算法模板

、
Dijstra

找到最小距离 依次将点拉入集合中
然后进行更新各点到集合的最小距离<span id="transmark"></span>
重复n-1次

注意边重复出现但权值不同的情况
 #include<iostream>
#include<cstring>
#include<cstdlib>
#include<cstdio>
#include<cmath>
#define INF 0x3f3f3f3f
using namespace std;
int Map[1000][1000];
int low[1000];
int vis[1000];
int n,m;
int Dijkstra(int ans)
{
    for(int i=1;i<=n;i++)
    {
        low[i]=Map[i][ans];
    }
    low[ans]=0;
    vis[ans]=1;
    for(int i=1;i<n;i++)
    {
        int k=-1;
        int Min=INF;
        for(int j=1;j<=n;j++)
        {
            if(Min>low[j]&&!vis[j])    ///找出距离最小的,拉入集合
            {
                Min=low[j];
                k=j;
            }
        }
        if(k==-1)break;
        vis[k]=1;                     ///拉到集合
        for(int j=1;j<=n;j++)
        {
            if(low[j]>Map[j][k]+low[k])   ///更新其他点到集合点的距离
            {
               low[j]=Map[j][k]+low[k];
            }
        }
    }
}
int main()
{
    while(~scanf("%d%d",&n,&m))
    {
        if(m==0)
        {
            printf("0\n");
            continue;
        }
        memset(Map,INF,sizeof(Map));
        memset(vis,0,sizeof(vis));
        for(int i=0;i<m;i++)
        {
            int a,b,c;
            scanf("%d%d%d",&a,&b,&c);
            if(Map[a][b]>c)        ///已经存在边
            {
                 Map[a][b]=c;
                 Map[b][a]=c;
            }
        }
        Dijkstra(1);
        printf("%d\n",low[n]);
    }
    return 0;
}

Bellman
每次都添加一个边然后求最短路
动态规划的过程

///注意无向的处理
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<cstdio>
#include<cmath>
#define INF 0x3f3f3f3f
using namespace std;
struct node
{
    int u,v,w;
}p[100100];
int n,m;
int dis[1000];
int ans;
int Bellman()
{
    for(int i=1;i<=n;i++)
        dis[i]=INF;
    dis[1]=0;
    for(int i=0;i<n-1;i++)    ///添加i个边时的最小路径
    {
        for(int j=0;j<ans;j++)
        {
            if(dis[p[j].v]>dis[p[j].u]+p[j].w)    ///动态规划 松弛
            {
                dis[p[j].v]=dis[p[j].u]+p[j].w;
            }
        }
    }
}
int main()
{
    while(~scanf("%d%d",&n,&m))
    {
       /// memset(vis,0,sizeof(vis));
       ans=0;
        for(int i=0;i<m;i++)
        {
            int u,v,w;
            scanf("%d%d%d",&u,&v,&w);
            p[ans].u=u;                   ///双向的
            p[ans].v=v;
            p[ans++].w=w;
            p[ans].u=v;
            p[ans].v=u;
            p[ans++].w=w;
        }

        Bellman();
        printf("%d\n",dis[n]);
    }
    return 0;
}

///注意无向的处理
前向星 +  SPFA(Bellman()+queue)
将所有的边
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<cstdio>
#include<cmath>
#include<queue>
#define INF 0x3f3f3f3f
using namespace std;
struct node
{
    int u,v,w;
    int next;
} p[100100];
int n,m;
int dis[1000];
int head[10000];
int vis[1000];
int ans;
void Creat(int u,int v,int w)
{
    p[ans].u=u;                   ///双向的
    p[ans].v=v;
    p[ans].w=w;
    p[ans].next=head[u];
    head[u]=ans++;
    p[ans].u=v;
    p[ans].v=u;
    p[ans].w=w;
    p[ans].next=head[v];
    head[v]=ans++;
}
int SPFA()
{
    queue<int>q;
    q.push(1);
    vis[1]=1;
    dis[1]=0;
    while(!q.empty())
    {
        int u=q.front();
        q.pop();
        vis[u]=0;
        for(int i=head[u]; i!=-1; i=p[i].next)
        {
            int v=p[i].v;
            if(dis[v]>dis[u]+p[i].w)
            {
                dis[v]=dis[u]+p[i].w;
                if(!vis[v])
                {
                    q.push(v);
                    vis[v]=1;
                }
            }
        }
    }
}
int main()
{
    while(~scanf("%d%d",&n,&m))
    {
        memset(vis,0,sizeof(vis));
        memset(head,-1,sizeof(head));
        memset(dis,INF,sizeof(dis));
        ans=0;
        for(int i=0; i<m; i++)
        {
            int u,v,w;
            scanf("%d%d%d",&u,&v,&w);
            Creat(u,v,w);
        }
        SPFA();
        printf("%d\n",dis[n]);
    }
    return 0;
}


你可能感兴趣的:(最短路算法模板)