基于邻接表的Dijkstra算法

迪杰斯特拉(Dijkstra)算法

定义

Dijkstra(迪杰斯特拉)算法是计算单源最短路径算法,用于计算一个结点到其他所有结点的最短路径。该算法以源点为起始点,不断更新其他点到已经确定距离结点的距离,选取距离最小的结点加入S集合,直到S集合存放有所有的结点

算法思想

现在一张图中有n个结点,有两个集合,S集合和V集合。S集合表示已经选取的结点,V集合表示还没有选取的结点

确定一个源点,放入S集合,剩下n-1个结点放入V集合
计算从源点经过S集合中的各点到达V集合中各点的距离,与之前确定的距离进行比较,如果新计算的距离小于原先的距离则更新该结点的距离,否则不更新距离,并选取距离最小的结点放入S集合,直到V集合为空(在计算过程中直接计算从最后加入S集合的点到源点的距离+最后加入S集合的点到V集合中各点的距离,表示从源点到达V集合中各点要经过最后加入S集合中的点,与原来的距离比较即可)

案例

在这里插入图片描述
代码

#include <iostream>
#include<string>
#include<vector>
using namespace std;

struct Node {
    int id;
    struct Node* next;
    int distance;
};

int Dijkstra(vector<Node*> distance, int a, int b) {
    vector<bool> s(distance.size(), true);
    vector<int> d(distance.size(), 65535);
    s[a] = false;
    Node* p = distance[a];
    while (p!=nullptr)
    {
        d[p->id] = p->distance;
        p = p->next;
    }
    for (int i = 1; i < distance.size()-1; i++) {
        int dl = 65535;
        int k=0;
        for (int j = 1; j < distance.size(); j++)
        {
            if (s[j] && d[j] < dl) {
                k = j;
                dl = d[j];
            }
        }
        if (k == 0)break;
        s[k] = false;
        Node* p = distance[k]->next;
        while (p!=nullptr) {
            if(s[p->id] && d[p->id] > d[k] + p->distance){
                d[p->id] = d[k] + p->distance;
            }
            p = p->next;
        }
    }
    return d[b];
}

int main()
{
    int n,a,b,i;
    cin >> n;
    vector<Node*> distance(n+1, nullptr);
    for (int i = 1; i < distance.size(); i++)
    {
        distance[i] = (Node*)malloc(sizeof(Node));
        distance[i]->id = i;
        distance[i]->next = nullptr;
        distance[i]->distance = 0;
    }
    cin >> i;
    cin >> a>>b;
    while (i--)
    {
        int k1, k2, d;
        cin >> k1 >> k2 >> d;
        Node* p = (Node*)malloc(sizeof(Node));
        p->distance = d;
        p->id = k2;
        p->next = nullptr;
        Node* q = distance[k1];
        while (q->next!=nullptr)
        {
            q = q->next;
        }
        q->next = p;
		//无向图
      /*  p = (Node*)malloc(sizeof(Node));
        p->distance = d;
        p->id = k1;
        p->next = nullptr;
        q = distance[k2];
        while (q->next != nullptr)
        {
            q = q->next;
        }
        q->next = p;*/
    }
    cout<<Dijkstra(distance, a, b);
}

测试

5
7
1 3
1 2 10
2 3 50
1 5 100
1 4 30
4 5 60
4 3 20
3 5 10

输出

50
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

dream1909

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

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

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

打赏作者

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

抵扣说明:

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

余额充值