最短路径dijkstra模板

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/Armstrong_rose/article/details/80328408

题目描述

第一行两个整数n m。n表示顶点个数(顶点编号为1~n),m表示边的条数。接下来m行表示,每行有3个数x y z。表示顶点x到顶点y边的权值为z。求源点为1的最短路径。
题目来源【坐在马桶上看算法】算法7:Dijkstra最短路算法

题目思路

这道题我只是想练练dijkstra模板,dijkstra主要由两个步骤组成:

  • 找到顶点 i 周围距离最近的点 u
  • u 加入集合(已确定最短路径的点的集合)
  • 利用u更新其他所有的点到源点的最短路径距离

代码

#include <iostream>
#include <stdio.h>
using namespace std;
#define inf 0x3f3f3f3f
#define max 100
//edge[i][j]记录i到j的边长,dis[i]记录到i的最短路径长,
//mask[i]记录i点是否加入集合,pre[i]记录i的最短路径上i的前一个点 
int edge[max][max],dis[max],mask[max],pre[max];
int main() {
    freopen("in.txt","r",stdin);
    int n,m;
    cin>>n>>m;
    //初始化edge[][],默认点到自己的边长为0,其他的默认为inf,即不可达 
    for(int i=1;i<=n;i++){
        for(int j=1;j<=n;j++){
            if(i==j) {
                edge[i][j]=0;
            }
            else {
                edge[i][j]=inf;
            }
        }
    }
    //输入边长 
    int a,b,w;
    for(int i=1;i<=m;i++){
        cin>>a>>b>>w;
        edge[a][b]=w;
    }
    //源点为1,所以看1周围的点(没有和1相邻的点距离会是inf) 
    for(int i=1;i<=n;i++){
        dis[i]=edge[1][i];//在这里用边去初始化距离 
        mask[i]=0;
        pre[i]=1;
    }
    mask[1]=1;//1为源点,让1被访问过 
    //dijkstra核心操作如下 
    for(int i=1;i<=n-1;i++){
        int min=inf;
        int u;
        //每一次选出和i最近的点u,加入集合(每次只选一个) 
        for(int j=1;j<=n;j++){
            if(mask[j]==0&&min>dis[j]){
                min=dis[j];
                u=j;
            }
        }
        //u加入集合 
        mask[u]=1;
        //根据u去更新其他点到源点的距离,因为可能经过u中转之后有的点和源点会更近(所以遍历所有点) 
        for(int v=1;v<=n;v++){
            if(dis[v]>dis[u]+edge[u][v]){
                dis[v] = dis[u]+edge[u][v];
                pre[v]=u;//以u为中转的话,v到源点的最短路径上v的前一个点就是u 
            }

        }
    }
    //输出最短路径长度结果 
    for(int i=1;i<=n;i++){
        cout<<dis[i]<<" ";
    }
    cout<<endl;
    //输出最短路径 
    for(int i=1;i<=n;i++){
        int nn=i;
        while(nn!=1){
            cout<<nn<<"-";
            nn=pre[nn];
        }
        cout<<"1"<<endl;
    }
    fclose(stdin);
    return 0;
}

输入:
6 9
1 2 1
1 3 12
2 3 9
2 4 3
3 5 5
4 3 4
4 5 13
4 6 15
5 6 4
输出:
0 1 8 4 13 17
1
2-1
3-4-2-1
4-2-1
5-3-4-2-1
6-5-3-4-2-1

没有更多推荐了,返回首页