首页 > 编程语言 >最短路之dijkstra算法

最短路之dijkstra算法

时间:2023-07-19 17:13:21浏览次数:46  
标签:dist int 短路 dijkstra 算法 dist1 dist2 first

dijkstra比之上次介绍的的bellman-ford算法的用途上最大的区别就是dijkstra只可用于求无负权边图中的最短路,堆优化后的dij比bellman-ford的复杂度(mn)更小(mlogn)


代码源关于dijkstra的解释

简单来讲就是每次选出一个没被选过的离起点最近的点,松弛这个点所在的每个边,直到所有点都被选过。这样dist[n]就是起点到n的最短路

简单来讲就是每次选出一个没被选过的离起点最近的点,松弛这个点所在的每个边,直到所有点都被选过。这样dist[n]就是起点到n的最短路

对于每次选出一个没被选过的离起点最近的点我们可以用小根堆进行操作


例题1 dijkstra模板

给你一张 n 个顶点 m 条边的有向简单图,顶点编号从 1 到 n,每条边都有一个边权,边权为非负整数。

现在有 k 组询问,每组询问读入两个整数 x,y请求出从 x 号点到 y 号点的最短路的长度。如果不存在从 x 号点到 y 号点的路径,请输出 -1。

输入格式

第一行三个整数 n,m,k,表示图的顶点数、边数和询问次数。

接下来 m 行,每行三个整数 x,y,z,表示 x 号点到 y 号点有一条边权为 z 的有向边。

接下来 k 行,每行两个整数 x,y,表示一组询问。

输出格式

输出共 k 行,每行一个数表示一组询问的答案。

样例输入

3 3 2
1 2 3
2 3 2
3 2 1
1 3
3 1
样例输出

5
-1
数据规模

对于所有数据,保证 2≤n≤100000,0≤m≤200000,1≤k≤5,1≤x,y≤n,1≤z≤10000

代码

# include<bits/stdc++.h>
 
using namespace std;
 
typedef pair<int,int> pii;
 
const int N = 1e5+10,M = 2e5+10;
 
vector<pii> edge[N];	//edge数组存的是pair类型 {终点,权值} edge[x]的值为{y,w} 意味着一条起点为x终点为y权值为w的边
int dist[N];			//每个点到起点的距离
 
int n,m,k;
int dijkstra(int x,int y)
{
	priority_queue<pii,vector<pii>,greater<pii> > q;	//这个小根堆存的是{dist[i],i}
	memset(dist,0x3f,sizeof dist);
	dist[x] = 0;
	q.push({dist[x],x});	//最开始先把起点dist值设为0,传入堆
	while(q.size())
	{
		auto t = q.top();
		q.pop();
		int x = t.first;
		for(auto i:edge[t.second]) 	//类似于bfs的写法,将最近的点进队然后松弛临边
		{
			 if(dist[i.first] > x + i.second)
			 {
			 	dist[i.first] = x + i.second;
				q.push({dist[i.first],i.first});
			 }
		}
	}
	return dist[y];
	}
 
int main()
{
	cin>>n>>m>>k;
	while(m--)
	{
		int x,y,z;scanf("%d%d%d",&x,&y,&z);	
		edge[x].push_back({y,z});
	}
	while(k--)
	{
		int x,y;
		scanf("%d%d",&x,&y);
		int ans = dijkstra(x,y);
		if(ans == 0x3f3f3f3f) cout<<"-1"<<endl;
		else cout<<ans<<endl;
	}
	
	return 0;
}

例题2(这道题在bellman-ford的文章里写过,在这里再写一遍)

小蜗要在城市中租房子,他想要找到一处合适的住址,使得住址到商场、工作地点、医院的距离和最小。城市可以抽象为一张 n 个点 m 条边的无向简单图,顶点编号从 1 到 n,每条边都有一个边权,边权为非负整数。

输入格式
第一行两个整数 n,m,表示图的顶点数和边数。

接下来 m 行,每行三个整数 x,y,z,表示 x 号点和 y 号点之间有一条边权为 z 的边。

接下来一行三个整数 a,b,c,分别表示商场、工作地点、医院所在的顶点的编号。

输出格式
你需要寻找一个合适的住址(住址必须为 n 个顶点中的某个点,这个点可以和 a,b,c 重合),并输出一行一个整数表示住址到商场、工作地点、医院的最小距离和。

样例输入
4 3
1 2 1
2 3 1
3 4 1
1 2 4
样例输出
3
数据规模
对于所有数据,保证 3≤n≤5000,0≤m≤10000,1≤x,y,a,b,c≤n,1≤z≤10000保证整张图连通并且 a,b,c 两两不同。


这道题之前在bellmanford那篇文章中写过一遍,这次再用dijkstra写一遍,思路还是一样的:分别以a,b,c为起点做三次dijkstra建立三个dist数组然后遍历每个点求dist1+dist2+dist3的最小值

代码

# include<bits/stdc++.h>
 
using namespace std;
 
typedef pair<int,int> pii;
 
const int M = 1e4+10;
const int N = 5e3+10;
 
vector<pii> edge[2*M+1];
int dist[N],dist1[N],dist2[N],dist3[N];
int a,b,c;
 
void dijkstra(int x)
{
	memset(dist,0x3f,sizeof dist);
	dist[x] = 0;
	priority_queue<pii,vector<pii>,greater<pii> > q;
	q.push({dist[x],x});
	while(q.size())
	{
		auto t = q.top();
		q.pop();
		for(auto i:edge[t.second])
		{
			if(dist[i.first]>t.first+i.second)
			{
				dist[i.first] = t.first+i.second;
				q.push({dist[i.first],i.first});
			}
		}
	}
	
}
int main()
{
	int n,m;cin>>n>>m;
	for(int i=0;i<m;i++) 
	{
		int x,y,z;scanf("%d%d%d",&x,&y,&z);
		edge[x].push_back({y,z});	
		edge[y].push_back({x,z});	
	}	
	scanf("%d%d%d",&a,&b,&c);
	dijkstra(a);memcpy(dist1,dist,sizeof dist);
	dijkstra(b);memcpy(dist2,dist,sizeof dist);
	dijkstra(c);memcpy(dist3,dist,sizeof dist);
	int ans = 100000;
	for(int i=1;i<=n;i++)
	{
		ans = min(ans,dist1[i]+dist2[i]+dist3[i]);
	}
	cout<<ans<<endl;
	return 0;
}

例题3

小蜗要在城市中租房子,他想要找到一处合适的住址,使得住址到商场、工作地点、医院的距离和最小。城市可以抽象为一张 n 个点 m 条边的无向简单图,顶点编号从 1 到 n,每条边都有一个边权,边权为非负整数。

输入格式
第一行两个整数 n,m,表示图的顶点数和边数。

接下来 m

标签:dist,int,短路,dijkstra,算法,dist1,dist2,first
From: https://www.cnblogs.com/algoshimo/p/17565749.html

相关文章

  • 最短路之 Bellman-ford 算法
    bellman-ford算法的思想:若有向图有n个点,m条边。扫描所有边,对每条边进行一次松弛(即对a,b为端点,权重为w的边,dist[b]=min(dist[a],dist[a]+w))重复此流程(最多重复n次)直到没有更新操作发生例题1bellmanford板子给你一张n个顶点m条边的有向简单图,顶点编号从1到......
  • 历年检测、分割、生成算法梳理(2023)
    检测算法 分割算法 生成算法 ......
  • 雷达算法 | 一种适用于汽车雷达的聚类算法研究与分析
    公众号【调皮连续波】,其他平台为自动同步,同步内容若有不全或乱码,请前往公众号阅读。保持关注调皮哥,获得更多雷达干货学习资料和建议,助力大家轻松、快乐、有方向地学习雷达技术。本文参考TI的一种适用于汽车雷达的聚类算法研究和实现.pdf文档由于不涉及硬件,因此本文仅对算法部分进行......
  • 校招 | 2023届应届生毫米波雷达算法岗秋招经历分享
    本文首发于公众号【调皮连续波】,其他平台为自动同步,同步内容若有不全或乱码,请前往公众号阅读。保持关注调皮哥,获得更多雷达干货学习资料和建议,助力大家轻松、快乐、有方向地学习雷达技术。知乎:https://zhuanlan.zhihu.com/p/576656211。原创作者: @探索Seeker本文经过原创作者同意,......
  • 字典树(trie) 算法笔记
    P1字典树是什么顾名思义就像一个字典一样,可以查询某单词是否出现,也可以查找同一前缀的单词的个数等等操作。P2字典树的实现字典树是用树来实现的(这不废话吗),如果从根节点走到一个已标记过的节点(后面我们会称它为单词节点)的一条路径就是一个单词。我们定义一下变量(或数组)的表......
  • 代码随想录算法训练营第三十三天| 1049. 最后一块石头的重量 II 494. 目标和 474.一
    1049.最后一块石头的重量II思路:因为含有两个石头的相撞,所以需要把dp的目标值改成sum/2,然后取得这个目标值的最大值,然后对sum-2*target代码:1//要求:有多个石头,两两撞击,取得剩下的石头的最小值2//——》一定要碰到最后一个3//注意:4//1,x==y:两个粉碎,x<y:y=......
  • m基于虚拟力优化算法的二维室内红外传感器部署策略matlab仿真
    1.算法仿真效果matlab2022a仿真结果如下:    2.算法涉及理论知识概要        红外传感器在室内环境监测、安防、智能控制等领域中得到了广泛应用。在室内部署红外传感器时,其位置的选择对于传感器的性能和信号质量有着至关重要的影响。因此,如何确定红外传感器......
  • 代码随想录算法训练营第57天 | ● 647. 回文子串 ● 516.最长回文子序列 ● 动
     第九章 动态规划part17●  647. 回文子串  ●  516.最长回文子序列●  动态规划总结篇 今天 我们就要结束动态规划章节了,大家激不激动!!!   详细布置   647. 回文子串    动态规划解决的经典题目,如果没接触过的话,别硬想 直接看题解。https:......
  • 代码随想录算法训练营第58天 | ● 739. 每日温度 ● 496.下一个更大元素 I - 第1
     第十章 单调栈part01 ●  739. 每日温度 ●  496.下一个更大元素 I    详细布置    739. 每日温度  今天正式开始单调栈,这是单调栈一篇扫盲题目,也是经典题。 大家可以读题,思考暴力的解法,然后在看单调栈的解法。 就能感受出单调栈的巧妙 ......
  • 代码随想录算法训练营第59天 | ● 503.下一个更大元素II ● 42. 接雨水 - 第10章
     第十章 单调栈part02 ●  503.下一个更大元素II ●  42. 接雨水    详细布置   503.下一个更大元素II  这道题和 739. 每日温度 几乎如出一辙,可以自己尝试做一做 https://programmercarl.com/0503.%E4%B8%8B%E4%B8%80%E4%B8%AA%E6%9B%B4%E5%......