单源最短路径-迪杰斯塔拉(Dijkstra)算法的实现

/************************************************************************
*
* 文件名:7.1.1.cpp
*
* 文件描述:Dijkstra算法的实现(好久没写代码了,看来我还是适合codeing不适合paper)
*
* 创建人:  fdk

* 时  间:  2018-09-03
*
* 版本号:1.0
*
* 修改记录:
*
************************************************************************/

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
#include<string>
#include<vector>
#include<stack>
#include<bitset>
#include<cstdlib>
#include<cmath>
#include<set>
#include<list>
#include<deque>
#include<map>
#include<queue>
#include<limits.h>
#define M 100
#define N 100
using namespace std;

typedef struct node
{
    int matrix[N][M];    //邻接矩阵
    int n;               //顶点数
    int e;               //边数
}MGraph;

void DijkstraPath(MGraph g, int *dist, int *path, int v0) //v0表示原顶点
{
    int i, j, k;
    bool visited[g.n];
    for (i = 0; i < g.n; i++)    //初始化
    {
        if (g.matrix[v0][i] > 0 && i != v0)
        {
            dist[i] = g.matrix[v0][i];
            path[i] = v0;              //path记录最短路径上v0到i的前一个顶点
        }
        else
        {
            dist[i] = INT_MAX;         //如果i不与v0直接相连,则权值为无穷大
            path[i] = -1;
        }
        visited[i] = false;            //初始化都未被访问过
    }
    dist[v0] = 0;                      //初始化最短距离为0
    visited[v0] = true;

    for (i = 0; i < g.n; i++)          //循环扩展n-1次
    {
        int min = INT_MAX;
        int u;
        for (j = 0; j < g.n; j++)     //寻找未被扩展的的权值最小的顶点
        {
            if (visited[j] == false && dist[j] < min)
            {
                min = dist[j];
                u = j;
            }
        }
        visited[u] = true;

        /*更新dist数组的值和路径的值*/
        for (k = 0; k < g.n; k++)
        {
            if (visited[k] == false && g.matrix[u][k] > 0 && min + g.matrix[u][k] < dist[k])
            {
                dist[k] = min + g.matrix[u][k];   //如果新加入的结点使得k的结点值变小则更新
                path[k] = u;
            }
        }

    }
}


void showPrint(int *path, int v, int v0)
{
    /*打印时需要从后往前推导,借用堆栈来实现顺序输出*/
    stack<int> s;
    int u = v;
    while (v != v0)
    {
        s.push(v);
        v = path[v];
    }
    s.push(v);

    while (!s.empty())
    {
        cout << s.top() << " ";
        s.pop();
    }
}
int main()
{
    int n, e; //n为顶点数,e为边数
    while (cin >> n >> e && e != 0)
    {
        int i, j;
        int s, t, w; //表示存在一条边s->t,权值为w
        MGraph g;
        int v0;

        int *dist = new int[n]; //最短距离
        int *path = new int[n]; //路径
        for (i = 0; i < n; i++)
        {
            for (j = 0; j < n; j++)
            {
                g.matrix[i][j] = 0;
            }
        }
        g.n = n;
        g.e = e;
        for (i = 0; i < e; i++)
        {
            cin >> s >> t >> w;
            g.matrix[s][t] = w;
        }
        cin >> v0;              //输入源顶点
        DijkstraPath(g, dist ,path , v0);
        for (i = 0; i < n; i++)
        {
            if (i != v0)
            {
                showPrint(path, i, v0);
                cout << dist[i] << endl;
            }
        }
    }
    return 0;
}


参考博客: https://www.cnblogs.com/dolphin0520/archive/2011/08/26/2155202.html 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值