最短路径

Cealivanus Kwan Lv3

image-20241002114518002

n:点数

m:边数

稠密图:

相对来说线比点多

显然易见,稠密图的路径太多了,所以就用点来找,也就是抓重点;

稀疏图:

相对来说点比线多

点很多,但是连线不是很多的时候,对应的就是稀疏图,稀疏图的路径不多,所以按照连接路径找最短路,这个过程运用优先队列,能确保每一次查找保留到更新到队列里的都是最小的,同时还解决了两个点多条路选择最短路的问题;

Dijkstra算法求解最短路

基于贪心算法

朴素Dijkstra算法

  1. dis[i]=INF dis[1]=0

    2.(s : 当前已确定最短距离的)

For i:0~n (循环n次可得n个结点的最短距离)

 t <- 不在s 中的距离最近的点
 
 s <- t
 
 用t更新其他点的距离

​ 更新方式: 判断l->x与l->t->x

     dis[x] > dis[t] + w

例题链接:849. Dijkstra求最短路 I - AcWing题库

image-20241002112209960

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;
const int N = 510;
int n,m;
int g[N][N], dist[N];
bool st[N];//表示第t个点是否确定路径

int dijkstra()
{
memset(dist,0x3f,sizeof(dist));//初始化正无穷
dist[1]=0;

for(int i=0;i<n;i++)
{
int t=-1;
for(int j=1;j<=n;j++)
if(!st[j]&&(t==-1||dist[t]>dist[j])) //t不是最短的 更新值
t=j;
st[t]=true;
for(int j=1;j<=n;j++)
dist[j] = min(dist[j],dist[t]+g[t][j]); //更新直达j和借由t到j的较短路
}

if(dist[n]==0x3f3f3f3f) return -1;//没有路径更新,无联通
return dist[n];
}

int main()
{
cin>>n>>m;
memset(g,0x3f,sizeof(g));
while(m--)
{
int a,b,c;
cin>>a>>b>>c;
g[a][b]=min(g[a][b],c);//防止c超出0x3f3f3f3f范围
}
int t=dijkstra();
cout<<t<<'\n';
return 0;
}

堆优化版Dijkstra

堆:手写堆或者优先队列——使用优先队列

例题链接:850. Dijkstra求最短路 II - AcWing题库

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
#include<iostream>
#include<cstring>
#include<algorithm>
#include<queue>
using namespace std;

typedef pair<int,int> PII;
const int N = 1e6+10;

int n,m,idx;
int h[N],
w[N],//权重
e[N],ne[N];
int dist[N];
bool st[N];//表示第t个点是否确定路径

void add(int a,int b,int c)
{
e[idx]=b,w[idx]=c,ne[idx]=h[a],h[a]=idx++;
}
int dijkstra()
{
memset(dist,0x3f,sizeof(dist));//初始化正无穷
dist[1]=0;

priority_queue<PII,vector<PII>,greater<PII>> heap;
heap.push({0,1});
while(heap.size())
{
auto t=heap.top();
heap.pop();
int ver=t.second,distance=t.first;
if(st[ver]) continue;
for(int i=h[ver];i!=-1;i=ne[i])
{
int j=e[i];
if(dist[j]>distance+w[i])
{
dist[j]=distance+w[i];
heap.push({dist[j],j});
}
}
}

if(dist[n]==0x3f3f3f3f) return -1;
return dist[n];
}

int main()
{
cin>>n>>m;
memset(h,-1,sizeof(h));
while(m--)
{
int a,b,c;
cin>>a>>b>>c;
add(a,b,c);
}
int t=dijkstra();
cout<<t<<'\n';
return 0;
}

待更新……

  • 标题: 最短路径
  • 作者: Cealivanus Kwan
  • 创建于 : 2024-10-14 22:06:59
  • 更新于 : 2024-12-19 22:29:32
  • 链接: https://redefine.ohevan.com/2024/10/14/最短路径/
  • 版权声明: 本文章采用 CC BY-NC-SA 4.0 进行许可。