首页 > 编程语言 >迪杰斯特拉算法实现最短路径

迪杰斯特拉算法实现最短路径

时间:2024-05-27 13:31:28浏览次数:26  
标签:pq 斯特拉 int newDistance 路径 迪杰 最短 当前 顶点

172f2488741b4a3e9bfe91426a6798d3.png1.用邻接表实现

1.先写出一个邻接表

 

#include <iostream>
#include <vector>
#include<queue>

using namespace std;

// 定义边结构体
struct Edge {
	int to; // 边指向的顶点
	int weight; // 边的权重,如果图是无权重的,可以省略这个成员
};

// 邻接表类
class AdjacencyList {
private:
	vector<vector<Edge>> adjacencyList; // 邻接表
	vector<int>distances;               //存储每个节点到原点的距离
public:
	// 获取邻接表
	vector<vector<Edge>>& getAdjacencyList() {
		return adjacencyList;
	}

	// 构造函数
	AdjacencyList(int numVertices) : adjacencyList(numVertices), distances(numVertices, INT_MAX) {}

	// 添加边(无向图)
	void addEdge(int from, int to, int weight = 1) {
		//{ to, weight }在这里创建了一个std::pair对象,用于存储边的信息,并将其添加到邻接表中。
		//{ to, weight }是一个std::pair,它包含两个值:to(表示边的终点顶点的编号)和weight(表示边的权重)。
		adjacencyList[from].push_back({ to, weight });
		adjacencyList[to].push_back({ from, weight }); // 无向图需要添加反向边
	}

	//dijiskstra获取最短路径
	vector<int>getShortestPath(int source) {
		//优先队列
		priority_queue<pair<int, int>, vector<pair<int, int>>, greater<pair<int, int>>> pq;
		//0-0的最短路径为0
		pq.push({ 0,source });
		//存储0到原点的距离为0
		distances[source] = 0;

		while (!pq.empty()) {
			//获取队列顶的元素0=current,将0到0的最短路径pop出队列-因为此时获取的队列顶元素有两个,一个是最短路径,一个是元素编号。所以使用auto自动识别元素类型
			auto current = pq.top();
			pq.pop();
			int currentDistance = current.first;//提取当前顶点到源顶点的最短路径长度。
			int currentVertex = current.second; //提取当前顶点的编号。

			//获取当前顶点所链接的所有点
			for (const Edge& edge : adjacencyList[currentVertex]) {
				//定义neighbor为当前顶点所连接的点
				int neighbor = edge.to;
				//定义newDistance为原点到当前点的最新的最短路径=原点到上一个点的最短路径+上一个点到当前点的权值
				int newDistance = currentDistance + edge.weight;
				//如果当前的最新最短路径小于链接当前节点的另一个节点的最短路径,则将原点到当前节点的值重新更新为newDistance
				if (newDistance < distances[neighbor]) {
					distances[neighbor] = newDistance;
					//更新完后将最短路径压入pq队列
					pq.push({ newDistance,neighbor });
				}
			}
		}
		return distances;
	}

	// 打印邻接表
	void print() {
		for (int i = 0; i < adjacencyList.size(); ++i) {
			cout << "Vertex " << i << ": ";
			for (const Edge& edge : adjacencyList[i]) {
				cout << "(" << edge.to << ", " << edge.weight << ") ";
			}
			cout << endl;
		}
	}

};

int main() {
	// 创建一个有6个顶点的邻接表
	AdjacencyList graph(6);

	// 添加边
	graph.addEdge(0, 1, 1);
	graph.addEdge(0, 2, 12);
	graph.addEdge(1, 2, 9);
	graph.addEdge(1, 3, 3);
	graph.addEdge(2, 3, 4);
	graph.addEdge(2, 4, 5);
	graph.addEdge(3, 4, 13);
	graph.addEdge(3, 5, 15);
	graph.addEdge(4, 5, 4);

	// 打印邻接表
   /* graph.print();*/

	vector<int>getnum = graph.getShortestPath(0);
	for (int num : getnum) {
		cout << num << endl;
	}
	return 0;
}

迪杰斯特拉算法实现最短路径函数

//欧氏距离
int OS(int x1, int y1,int x2,int y2) {
	return sqrt((x1-x2)* (x1 - x2) +(y1-y2)* (y1 - y2));
}

//dijiskstra获取最短路径
vector<int>getShortestPath(int source) {
	//优先队列
	priority_queue<pair<int, int>, vector<pair<int, int>>, greater<pair<int, int>>> pq;
	//0-0的最短路径为0
	pq.push({ 0,source });
	//存储0到原点的距离为0
	distances[source] = 0;

	while (!pq.empty()) {
		//获取队列顶的元素0=current,将0到0的最短路径pop出队列-因为此时获取的队列顶元素有两个,一个是最短路径,一个是元素编号。所以使用auto自动识别元素类型
		auto current = pq.top();
		pq.pop();
		int currentDistance = current.first;//提取当前顶点到源顶点的最短路径长度。
		int currentVertex = current.second; //提取当前顶点的编号。

		//获取当前顶点所链接的所有点
		for (const Edge& edge : adjacencyList[currentVertex]) {
			//定义neighbor为当前顶点所连接的点
			int neighbor = edge.to;
			//定义newDistance为原点到当前点的最新的最短路径=原点到上一个点的最短路径+上一个点到当前点的权值
			int newDistance = currentDistance + edge.weight;
			//如果当前的最新最短路径小于链接当前节点的另一个节点的最短路径,则将原点到当前节点的值重新更新为newDistance
			if (newDistance < distances[neighbor]) {
				distances[neighbor] = newDistance;
				//更新完后将最短路径压入pq队列,使后序查看与neighbor所连接的点
				pq.push({ newDistance,neighbor });
			}
		}
	}
	return distances;
}

1.用欧氏距离计算函数算出两个坐标点之间的距离

7c57b76163cf4b0196509eed48432ca7.png

 

2.用优先队列实现最短路径问题

 

1.先创建出一个优先队列pq,用pair类接受两个数据一个为当前点到原点的最短路径,一个为当前节点的定点编号,将输入队列的数据按最短路径长度从小到大排列,将原点0输入进队列,并用distances数组记录0-0的最短路径为0;

//优先队列
priority_queue<pair<int, int>, vector<pair<int, int>>, greater<pair<int, int>>> pq;
//0-0的最短路径为0
pq.push({ 0,source });
//存储0到原点的距离为0
distances[source] = 0;

2.当队列不为空时,一直寻找原点到当前顶点的最短路径,首先定义一个连变量current获取到此时队列的队首元素,然后将当前元素pop出队列,定义curentDistance获取当前pair类的第一个元素(当前顶点到原点的最短路径),定义currentVertex获取当前pair类的第二个元素(为当前顶点的编号)

int currentDistance = current.first;//提取当前顶点到源顶点的最短路径长度。
int currentVertex = current.second; //提取当前顶点的编号。

3.用for循环获取当前顶点所连接的所有点,定义neighbor为当前点所连接的顶点编号,定义newDistance为当前点到原点的最短路径=(上一个顶点到远点的最短路径+当前顶点到上一个顶点的边权)     如果当前顶点的最短路径小于当前节点所连接的另一个节点的最短路径,就更新当前节点的最短路径为新的最短路径,最后,将当前节的最短路径和当前顶点的编号输入优先队列pq,以进行下次的最短路径寻找;

	//获取当前顶点所链接的所有点
	for (const Edge& edge : adjacencyList[currentVertex]) {
		//定义neighbor为当前顶点所连接的点
		int neighbor = edge.to;
		//定义newDistance为原点到当前点的最新的最短路径=原点到上一个点的最短路径+上一个点到当前点的权值
		int newDistance = currentDistance + edge.weight;
		//如果当前的最新最短路径小于链接当前节点的另一个节点的最短路径,则将原点到当前节点的值重新更新为newDistance
		if (newDistance < distances[neighbor]) {
			distances[neighbor] = newDistance;
			//更新完后将最短路径压入pq队列,使后序查看与neighbor所连接的点
			pq.push({ newDistance,neighbor });
		}
	}
}
return distances;

 

 

标签:pq,斯特拉,int,newDistance,路径,迪杰,最短,当前,顶点
From: https://blog.csdn.net/2301_78947898/article/details/139126889

相关文章

  • 最短路-迪杰斯特拉(dijkstra)
    迪杰斯特拉(dijkstra)////CreatedbyLANSGANBSon2024/3/8.///**codetemplate:https://github.com/LANSGANBS/code-template*URL:*Status:*写完这道就去原*/#include<bits/stdc++.h>usingnamespacestd;usingi64=longlong;#defineendl'\n&......
  • 最短路-Floyd
    Floyd////CreatedbyLANSGANBSon2024/3/18.///**codetemplate:https://github.com/LANSGANBS/code-template*local:C:\Users\18019\CLionProjects\.cpp-code*URL:https://www.luogu.com.cn/problem/B3647*Status:AC*写完这道就去原*/#include<......
  • 最短路径
    拓扑序有这样一个问题:我们给定一张\(n\)个点\(m\)条边的有向无环图(DAG),请求出从\(1\)号结点出发,到达任意结点的最短路径,保证\(s\)可以到达任意结点,\(n,m\leq10^7\)。我们以下面这张图为例。如果我们想求\(1\rightarrow4\)的路径,我们不难发现,找到\(1\rightar......
  • PKUSC 2024 最短路径
    本文首发于QOJhttps://qoj.ac/blog/skip2004/blog/866大家好,我是钱哥,我来写一下PKUSC2024最短路径的题解。没有做过这个题的同学可以先自行做一做。我们下面来讲解一下如何一步步解决这个题目。subtask4首先,我们来解决第一个具有挑战性的子任务:\(m\leq2.5n\),这个点具......
  • dijkstra迪杰斯特拉算法(邻接表法)
    ​算法简易过程:迪杰斯特拉算法(朴素)O(n^2)G={V,E}V:点集合E:边集合初始化时令S={某源点ear},T=V-S={其余顶点},T中顶点对应的距离(ear,Vi)值若存在,d(ear,Vi)为弧上的权值,dist【i】若不存在,d(ear,Vi)为无穷大,dist【i】循环n-1次(n个点):1、从T中选......
  • 【CodeChef】Prison Escape(最短路)
    题目大意:给出一个01矩阵,求每个0移动(每次可以向有公共边的格子移动一步)到矩阵边界至少要经过多少个1。考虑建最短路模型,将矩阵中的每个位置拆分为入点和出点,矩阵外部设为一个点。枚举矩阵中的每个位置:如果这个位置在矩阵边界,矩阵外部向这个位置的入点连一条长度为0的边。......
  • P10447 最短 Hamilton 路径 题解
    P10447最短Hamilton路径题解题目传送门题意:给定一张有向带权图(\(n\le20\))求点\(0\)到点\(n-1\)的最短哈密顿路径。这是一道状压DP模板题。在状态压缩DP中,我们将一个集合压成一个二进制数。设\(f_{u,i}\)为已经走了集合\(u\)中的节点,且现在在点\(i\)的最短......
  • Dijkstra(迪杰斯特拉)
    Dijkstra(迪杰斯特拉)算法简单版须知首先用几个数组表示需要的状态:dis[] 表示距离从初始点到对应点的距离,初始点置为0,其他置为无穷graph[][]邻接矩阵,记录两点间连线的权重,可以记录无向图和有向图check[]判断当前点是否被记录算法思路:假定a为起点,每......
  • 单源最短路算法
    Dijkstra算法原理首先将所有点分为两类,确定和没确定最短路的点。首先我们可以知道,起点只能通过已经确定最短路的点去到其他点,所以我们可以不断的确定距离起点最近的点的路径长度,再用这个确定的点更新其他点到起点的最短路距离。此时找最近点为\(O(n)\),更新邻接点为\(O(m)\),......
  • 【最短路】网络延迟时间
    题源狄克斯特拉【待完成】classSolution:defnetworkDelayTime(self,times:List[List[int]],n:int,k:int)->int:g=[[float('inf')]*nfor_inrange(n)]forx,y,timeintimes:g[x-1][y-1]=timedist......