华农专业课拯救计划:迪杰斯特拉算法

1.题目整体复制,让你更快的找到我

【问题描述】

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

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

可将迪杰斯特拉算法描述如下:

在本题中,读入一个有向图的带权邻接矩阵(即数组表示),建立有向图并按照以上描述中的算法求出源点至每一个其它顶点的最短路径长度。

【输入形式】

输入的第一行包含2个正整数n和s,表示图中共有n个顶点,且源点为s。其中n不超过50,s小于n。

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

【输出形式】

只有一行,共有n-1个整数,表示源点至其它每一个顶点的最短路径长度。如果不存在从源点至相应顶点的路径,输出-1。

请注意行尾输出换行。

【样例输入】

4 1  //这里的1表示第2个顶点,0-1-2-3共计4个顶点,下图为有向图的邻接矩阵。
0 3 0 1
0 0 4 0
2 0 0 0
0 0 1 0

【样例输出】

6 4 7

【样例说明】

在本题中,需要按照题目描述中的算法完成迪杰斯特拉算法,并在计算最短路径的过程中将每个顶点是否可达记录下来,直到求出每个可达顶点的最短路径之后,算法才能够结束。 

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

另外需要注意的是,在本题中为了更方便的表示顶点间的不可达状态,可以使用一个十分大的值作为标记。

2.不废话,复制完整代码

#include<iostream>
using namespace std;
const int big = 99999;
const int size1 = 50;
int mat[size1][size1];
int dis[size1];
int visit[size1];
int num;
int start;
void dj()
{
    int i;
    int j;
    int k;
    for ( i = 0; i < num; i++)
    {
        dis[i] = big;
        visit[i] = 0;
    }
    dis[start] = 0;
    for (int j = 0; j < num; j++)
    {
        k = -1;
        for (i = 0; i < num; i++)
        {
            if (visit[i] == 0 && (k == -1 || dis[i] < dis[k]))
            {
                k = i;
            }
        }
        visit[k] = 1;
        for (int i = 0; i < num; i++)
        {
            if (visit[i] == 0 && dis[k] + mat[k][i] < dis[i])
            {
                dis[i] = dis[k] + mat[k][i];
            }
        }
    }
}
int main()
{
    scanf("%d%d", &num, &start);
    for (int i = 0; i < num; i++)
        for (int j = 0; j < num; j++)
        {
            scanf("%d", &mat[i][j]);
            if (mat[i][j] == 0)
                mat[i][j] = big;
        }
    dj();
    for (int i = 0; i < num; i++) {
        if (i != start) {
            if (dis[i] < big)
                printf("%d ", dis[i]);
            else
                printf("-1 ");
        }
    }
    return 0;
}

3.简单聊聊思想

首先解释一下变量的作用,一个是较大的值big,用于邻接矩阵中无权的值默认为无穷大,另一个是size1(size为关键字),表示构建数组的长度,邻接矩阵mat不必多说,dis存储的是源点到各点路径 的长度,,num存储的是图的顶点数,start为原点的位置,visit是传统的visit数组,讲解一下dj函数,首先将visit数组全部设置为未访问状态并将dis数组也就是各点到源点的距离设置为一个极大值,最后将dis[start]设置为0,因为自己到自己就是0,然后就是主循环,k的作用是最短路径背景下的终点的下标,初始化为-1.,然后遍历矩阵的每一行,如果该顶点未访问且还没有一个终点或者新点的下标小于已找到终点的下标,则将k的值赋值为终点值,等终点值确定下来后,visit数组的该点设置为已访问状态,然后更新dis数组,再遍历一遍列,如果该顶点处于未访问状态且该点的dis值大于确定终点+终点到源点边的权,则将该点的dis值更新,主函数首先是一个简单的带权邻接矩阵的初始化,然后遍历dis数组,当终点不为源点且该点的dis值不是big时,打印,否则打印-1

评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值