单源最短路径—Dijkstra算法

本文详细介绍了单源最短路径问题(SSSP)及其解决方案——Dijkstra算法。通过使用邻接矩阵和链式前向星两种数据结构实现算法,文章提供了完整的C++代码示例,帮助读者理解并应用Dijkstra算法解决实际问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

 

单源最短路径

单源最短路径问题(Single Source Shortest Path, SSSP问题)是说,给定一张有向图G=(V,E),V是点集,E是边集,|V|=n,|E|=m,节点以[1,n]之间的连续整数编号,(x, y, z)描述从x出发,到达y,长度为z的有向边。

 

Dijkstra算法

  1. 初始化d[起点] = 0,其余的点为正无穷。
  2. 找出一个未被标记,d[x]最小的点
  3. 标记,扫描所有出边,若找到更小的,则用其更新。
  4. 重复2、3,直到所有点被标记。

邻接矩阵:

 1 #include<iostream>
 2 #include<cstring>
 3 using namespace std;
 4 const int SIZE = 3010;
 5 int a[SIZE][SIZE], d[SIZE], m, n;
 6 bool v[SIZE];
 7 
 8 void dijkstra(){
 9     memset( d, 0x3f, sizeof d );
10     memset( v, 0, sizeof v );
11     d[1] = 0;
12     for( int i = 1; i < n; i++ ){
13         int x = 0;
14         for( int j = 1; j <= n; j++ )
15             if( !v[j] && ( x == 0 || d[j] < d[x] ) ) x = j;
16         v[x] = 1;
17         for( int y = 1; y < n; y++ )
18             d[y] = min( d[y], d[x] + a[x][y] );        
19     }
20 }
21 int main(){
22     cin >> n >> m;
23     memset( a, 0x3f, sizeof a );
24     for( int i = 1; i <= n; i++ ) a[i][i] = 0;
25     for( int i = 1; i <= m; i++ ){
26         int x, y, z;
27         cin >> x >> y >> z;
28         a[x][y] = min( a[x][y], z );
29     }
30     dijkstra();
31     for( int i = 1; i <= n; i++ ){
32         cout << d[i] <<"\n";
33     }
34     
35     return 0;
36 }

链式前向星:

 1 #include<iostream>
 2 #include<queue>
 3 #include<cstring>
 4 #include<cstdio>
 5 using namespace std;
 6 const int N = 100010, M = 1000010;
 7 int head[N], ver[N], Next[N], edge[N], d[N];
 8 bool v[N];
 9 int m, n, tot;
10 priority_queue< pair<int, int> > q;
11 void add(int x, int y, int z){
12     ver[++tot] = y, edge[tot] = z;
13     Next[tot] = head[x], head[x] = tot;
14 }
15 void dijkstra(){
16     memset(d, 0x3f, sizeof d);
17     memset(v, 0, sizeof v);
18     d[1] = 0;
19     q.push(make_pair(0, 1));
20     while(q.size()){
21         int x = q.top().second; q.pop();
22         if(v[x]) continue;
23         v[x] = 1;
24         for(int i=head[x]; i; i=Next[i]){
25             int y = ver[i], z = edge[i];
26             if(d[y] > d[x] + z){
27                 d[y] = d[x] + z;
28                 q.push(make_pair(-d[y], y));
29             }
30         }
31     }
32 }
33 int main(){
34     cin >> n >> m;
35     for(int i=1; i<=m; i++){
36         int x, y, z;
37         cin >> x >> y >> z;
38         add(x, y, z);
39     }
40     dijkstra();
41     for(int i=1; i<=n; i++){
42         cout << d[i] <<"\n";
43     }    
44     return 0;
45 }

 

转载于:https://www.cnblogs.com/hnoi/p/11481843.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值