迪杰斯特拉算法求最短路径

  1. 4. 迪杰斯特拉算法求最短路径

【问题描述】

在带权有向图G中,给定一个源点v,求从v到G中的其余各顶点的最短路径问题,叫做单源点的最短路径问题。

在常用的单源点最短路径算法中,迪杰斯特拉算法是最为常用的一种,是一种按照路径长度递增的次序产生最短路径的算法。

请在本题中,读入一个有向图的带权邻接矩阵(即数组表示),建立有向图并参考《耿》教材中算法7.15,编程求出源点至图中每一个其它顶点的最短路径长度。

【输入形式】

输入的第一行依次是2个正整数n和s,表示图中共有n个顶点,且源点编号为s(顶点编号从0~n-1)。其中n不超过50,s小于n。

以后的n行中每行有n个用空格隔开的整数。对于第i行的第j个整数,如果大于0,则表示第i个顶点有指向第j个顶点的有向边,且权值为对应的整数值;如果这个整数为0,则表示没有i指向j的有向边。当i和j相等的时候,对应的整数也是0。

【输出形式】

只有一行,共有n-1个整数,表示源点至其它每个顶点 (编号从小到大顺序) 各自的最短路径长度。如果不存在从源点至相应顶点的路径,则输出-1。

注意: 各输出数据间用1个空格分隔, 行尾输出换行。

【样例输入】

4  1
0 3 0 1
0 0 4 0
2 0 0 0
0 0 1 0

【样例输出】

6 4 7

【样例说明】

在本题中,需要在计算最短路径的过程中将每个顶点是否可达记录下来(可用非常大的整数来标记不可达),直到求出每个可达顶点的最短路径之后,算法才能够结束。 

迪杰斯特拉算法的特点是按照路径长度递增的顺序,依次添加下一条长度最短的边,从而不断构造出相应顶点的最短路径。 

#include <bits/stdc++.h>
const int INF = 9999999;
using namespace std;
int arc[505][505];
int n;
int start;
int dis[505];
int s[505] = {0};
void create()
{
    cin >> start;
    int data;
    for (int i = 0; i < n; i++)
    {
        for (int j = 0; j < n; j++)
        {
            cin >> data;
            if (data)
                arc[i][j] = data;
            else
                arc[i][j] = INF;
        }
    }
}
int findmin()
{
    int min = 2000;
    int u = -1;
    for (int i = 0; i < n; i++)
    {
        if (s[i] == 0 && min > dis[i])
        {
            min = dis[i];
            u = i;
        }
    }
    return u;
}
void show()
{
    for (int i = 0; i < n; i++)
    {
        if (dis[i])
        {
            if (dis[i] < INF)
                cout << dis[i] << " ";
            else
                cout << -1 << " ";
        }
    }
}
void dijkstra()
{
    int min;
    for (int i = 0; i < n; i++)
    {
        dis[i] = INF;
        s[i] = 0;
    }
    dis[start] = 0;
    for (int i = 0; i < n; i++)
    {
        int min = findmin();
        if (min == -1)
            return;
        s[min] = 1;
        for (int j = 0; j < n; j++)
        {
            if (s[j] == 0 && (arc[min][j] != INF) && dis[j] > dis[min] + arc[min][j])
            {
                dis[j] = dis[min] + arc[min][j];
            }
        }
    }
}
int main()
{
    cin >> n;
    create();
    dijkstra();
    show();
}

  • 3
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Wrong Ansewer

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值