当前位置: 首页 > article >正文

蓝桥杯之最短路径算法

Dijkstra算法

算法思想

该算法是典型的单元最短路径算法,用于计算一个节点到其他所有节点的最短路径

主要特点是以起始点为中心向外层层扩展,直到扩展到终点为止

实际上是为了计算从起始节点到其他所有节点的最短路径

代码实现

using uint = unsigned int;
const uint INF = 2160000;
//int Dijkstra(vector<vector<uint>>& graph, int start, int end)
//{
//	//表示起始节点到每个节点的距离
//	vector<uint>dis(graph.size(), 0);
//	//表示节点在s集合中(true),在u集合中为(false)
//	vector<bool>use(graph.size(), 0);
//	vector<int>path(graph.size(), 0);
//	//初始化dis
//	for (int i = 0; i < graph.size(); i++)
//	{
//		dis[i] = graph[start][i];
//	}
//	//将起始节点放到s集合中
//	use[start] = true;
//	path[start] = 1;
//	//开始将u集合中的节点依次放到s集合中
//	for (int j = 1; j < graph.size(); j++)
//	{
//		//找权值最小的节点
//		int k = -1;//记录该节点的下标
//		int min = 0xff;//记录该节点的权值
//		for (int i = 0; i < graph.size(); i++)
//		{
//			if (use[i] == false && dis[i] < min)
//			{
//				min = dis[i];
//				k = i;
//			}
//		}
//		if (k == -1)
//		{
//			break;
//		}
//		//将该节点放到s集合里,还要更新u集合里的权值
//		use[k] = true;
//		for (int i = 0; i < graph.size(); i++)
//		{
//			if (use[i] == false && min + graph[k][i] < dis[i])
//			{
//				dis[i] = min + graph[k][i];
//				path[k] = 1;
//			}
//		}
//	}
//	for (int i : path)
//	{
//		cout << i << " ";
//	}
//	cout << endl;
//	return dis[end];
//}
//优先级队列的优化
int Dijkstra(vector<vector<uint>>& graph, int start, int end)
{
	//表示起始节点到每个节点的距离
	vector<uint>dis(graph.size(), 0);
	//表示节点在s集合中(true),在u集合中为(false)
	vector<bool>use(graph.size(), 0);
	vector<int>path(graph.size(), 0);
	//用优先级队列(设置为小根堆),在找权值最小的节点中可以节约时间
	priority_queue<pair<uint , int>, vector<pair<uint, int>>, greater<pair<uint, int>>>que;
	//将起始节点放到s集合中
	use[start] = true;
	path[start] = 1;
	//初始化dis
	for (int i = 0; i < graph.size(); i++)
	{
		dis[i] = graph[start][i];
		//将除起始外的元素全部放在队列里面
		if(i!=start)
			que.emplace(dis[i],i);
	}
	while(!que.empty())
	//开始将u集合中的节点依次放到s集合中	while(!que.empty())
	{
		//因为我用的是优先级队列,那么队列首的元素一定是权值最小的元素
		auto pair = que.top();
		que.pop();
		//找权值最小的节点
		int k = pair.second;//记录该节点的下标
		uint min = pair.first;//记录该节点的权值
		if (min == INF)
		{
			break;
		}
		if (use[k])
			continue;
		//将该节点放到s集合里,还要更新u集合里的权值
		use[k] = true;
		for (int i = 0; i < graph.size(); i++)
		{
			if (use[i] == false && min + graph[k][i] < dis[i])
			{
				dis[i] = min + graph[k][i];
				path[k] = 1;
				//更新队列里的值
				que.emplace(dis[i], i);
			}
		}
	}
	for (int i : path)
	{
		cout << i << " ";
	}
	cout << endl;
	return dis[end];
}
int main()
{
	vector<vector<uint>>graph = {
		{0,6,3,INF,INF,INF},
		{6,0,2,5,INF,INF},
		{3,2,0,3,4,INF},
		{INF,5,3,0,2,3},
		{INF,INF,4,2,0,5},
		{INF,INF,INF,3,5,0}
	};
	//int distance = Dijkstra(graph, 1, 3);
	//cout << distance;
	 

Floyd算法

算法思想

多源最短路径算法:又称插点法,是一种利用动态规划思想寻找给定的加权图中多元点之间的算法主要思想是:

1,从第1个点到第n个点依次加入图中,每个点加入后进行试探是否有最短路径长度被更改,具体方法是遍历图中每一个节点(i,j双重循环),判断每一个点对距离是否因为加入的点而发生最小的距离变化,如果发生,就更新两点(i,j)的距离

2,重复上述直到最后插点完成

代码实现

	vector<vector<uint>>graph = {
		{0,6,3,INF,INF,INF},
		{6,0,2,5,INF,INF},
		{3,2,0,3,4,INF},
		{INF,5,3,0,2,3},
		{INF,INF,4,2,0,5},
		{INF,INF,INF,3,5,0}
	};
	//int distance = Dijkstra(graph, 1, 3);
	//cout << distance;
	 
	 
	 
	
	//floyd算法
	for (int k = 0; k < graph.size(); k++)
	{
		for (int i = 0; i < graph.size(); i++)
		{
			for (int j = 0; j < graph.size(); j++)
			{
				graph[i][j] = min(graph[i][j], graph[i][k] + graph[k][j]);
			}
		}
	}
	for (auto i : graph)
	{
		for (auto j : i)
		{
			cout << j << " ";
		}
		cout << endl;
	}
	return 0;


http://www.kler.cn/a/550559.html

相关文章:

  • 【苍穹外卖】学习
  • 冒险岛079 V8 整合版源码搭建教程+IDEA启动
  • leetcode:643. 子数组最大平均数 I(python3解法)
  • SQL复习
  • 从零开始部署DeepSeek:基于Ollama+Flask的本地化AI对话系统
  • 【深度学习】环境和分布偏移
  • 如何用「教小狗」和「自动驾驶」讲明白 PPO 强化学习?
  • jetson orin nano super AI模型部署之路(一)deepseek r1模型部署
  • 什么是 SQL 注入?
  • Java:单例模式(Singleton Pattern)及实现方式
  • 如何commit后更新.gitignore实现push
  • 1-14 Merge与rebase操作
  • Linux:TCP和守护进程
  • Docker 与持续集成 / 持续部署(CI/CD)的集成(二)
  • Java 大视界 -- 开源社区对 Java 大数据发展的推动与贡献(91)
  • 【HF设计模式】07-适配器模式 外观模式
  • 【Elasticsearch】`nested`字段和`join`字段的区别
  • 三菱PLC实现100楼双电梯控制
  • Linux 外设驱动 应用 6 陀螺仪实验
  • 超低失真、超高清晰度的远心工业镜头