迪杰斯特拉(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