漫话算法:最短路径迪特拉斯算法

122 篇文章 0 订阅
95 篇文章 0 订阅
#include<iostream>
using namespace std;
int P[200];
int D[200];
typedef struct grap
{
    int point[200];
    int edge[200][200];
    int nump;
    int nume;
}grape;
void creat(grape* G)
{
    int n;
    int e;
    int vi;
    int vj;
    int w;
    printf("输入顶点数和边数\n");
    cin >> n >> e;
    G->nump = n;
    G->nume = e;
    for (int i = 0; i < n; i++)
    {
        for (int j = 0; j < n; j++)
        {
            if (i == j)
            {
                G->edge[i][j] = 0;
            }
            else
            {
                G->edge[i][j] = 9999;
            }
        }
    }
    for (int i = 0; i < G->nump; i++)
    {
        printf("输入第%d个节点信息", i + 1);
        cin >> G->point[i];
    }
    for (int i = 0; i < G->nume; i++)
    {
        printf("输入第%d条边的信息和权", i + 1);
        cin >> vi >> vj >> w;
        G->edge[vi][vj] = w;
    }

}
void dtls(grape* G, int v0, int* p, int* d)
{
    int k;
    int final[200];
    for (int i = 0; i < G->nump; i++)
    {
        final[i] = 0;
        d[i] = G->edge[v0][i];
        p[i] = -1;
    }
    final[v0] = 1;
    d[v0] = 0;
    for (int i = 1; i < G->nump; i++)
    {
        int min = 9999;
        for (int j = 0; j < G->nump; j++)
        {
            if (final[j] != 1 && d[j] < min)
            {
                min = d[j];
                k = j;
            }
        }
        final[k] = 1;
        for (int j = 0; j < G->nump; j++)
        {
            if (min + G->edge[k][j] < d[j] && final[j] == 0)
            {
                d[j] = min + G->edge[k][j];
                p[j] = k;
            }
        }
    }

}
int main()
{
    grape *G = new grape;
    int p[200];
    int d[200];
    creat(G);
    int v0 = 0;
    dtls(G, v0, p, d);
    for (int i = 1; i < G->nump; i++)
    {
        printf("v%d - v%d:", v0, i);
        int j = i;
        while (p[j] != -1)
        {
            printf("%d", p[j]);
            j = p[j];
        }
        printf("\n");
    }
    printf("最短路径长度");
    for (int i = 1; i < G->nump; i++)
    {
        printf("%d->%d:%d\n", G->point[0], G->point[i], d[i]);
    }
    return 0;
}

矩阵如果有边则存入权值,否则存入一个较大的数,k是最短路径的下标,final与visited数组作用相同,p储存最短路径下标,d表示v到v0的最短路径长度,然后看第一个顶点也就是矩阵的第0行,最短路径下标初始化为-1,再将数据放到d数组里面,然后自己的到自己的路径长度为0,然后就是主循环,如果该点没有被访问且最短路径长度小于当前记录的最小值,则将该点设为最短路径并更新最小值,然后将最终确定的节点标记到final数组中,然后将目标转向k进行继续计算,如果min+k的某条边的权重小于原来d中的值,修改d中的值和p中的值

  • 4
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值