Dijkstra算法(带路径模板)

个人心得:Dijkstra算法是贪心思想的一种延伸,注意路径pre,pre数组表示此时最短路径中的前一个顶点。每次更新到目的点时更新;

从源点出发,更新路径,然后找出此时最短的点,然后以这个点为头,看能否缩减路程,

#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<iomanip>
#include<algorithm>
using namespace std;
#define inf 1<<29
#define nu 10005
#define maxnum 100000
int n,m;
int c[nu][nu];
int dist[nu];
int pre[nu];
int book[nu];
void dijkstra(int n,int v){
  int i,j;
  memset(book,0,sizeof(book));
  for(i=1;i<=n;i++){
    dist[i]=c[v][i];
    if(dist[i]>maxnum) pre[i]=0;
    else pre[i]=v;
  }
  dist[v]=0;
  book[v]=1;
  for(i=1;i<n;i++){
    int temp=maxnum;
    int u=v;
    for(j=1;j<=n;j++){
        if(!book[j]&&dist[j]<temp)
            u=j,temp=dist[j];
    }
    book[u]=1;
    for(j=1;j<=n;j++){
        if(!book[j]&&c[u][j]<maxnum)
        {
            if(dist[j]>dist[u]+c[u][j]){
                dist[j]=dist[u]+c[u][j];
             pre[j]=u;
            }
        }
    }
  }
   for(int i=1;i<=n;i++)
    cout<<dist[i]<<endl;
}
void traceback(int v,int i,int pre[])
{
    cout<<i<<" <--";
    i=pre[i];
    if(i!=v) traceback(v,i,pre);
    if(i==v) cout<<i<<endl;
}
int main()
{
    cin>>n>>m;
    for(int i=0;i<nu;i++)
        for(int j=0;j<nu;j++)
        if(i!=j)
           c[i][j]=c[j][i]=maxnum;
    else
        c[i][j]=0;
    for(int i=1;i<=m;i++){
        int x,y,z;
        cin>>x>>y>>z;
        c[x][y]=c[y][x]=z;
    }
    dijkstra(n,2);
    traceback(2,4,pre);
    return 0;
}
原文地址:https://www.cnblogs.com/blvt/p/7896236.html