用题目来理解floyd与dijkstra【c/c++】

目录

题目描述

 输出描述

方法一:floyd

方法二:dijkstra


题目适合新手练习图论内容,这里用floyd,dijkstra算法就解决这道题,并且给出思路,以及需要注意的点。

题目描述

小明喜欢观景,于是今天他来到了蓝桥公园。已知公园有 N 个景点,景点和景点之间一共有 M 条道路。小明有Q个观景计划,每个计划包含一个起点 st 和一个终点 ed,表示他想从 st 去到 ed。但是小明的体力有限,对于每个计划他想走最少的路完成,你可以帮帮他吗?
输入描述

输入第一行包含三个正整数N,M,Q

第2到M+1行每行包含三个正整数u,v,w,表示u<—>v之间存在一条距离为w的路。

第M+2到M+Q-1行每行包含两个正整数st,ed,其含义如题所述

a53678ea7aaf4c72864259cec10ef831.png

 输出描述

输出共Q行,对应输入数据的查询。

若无法从st到达ed则输出-1

样例

输入

3 3 3
1 2 1
1 3 5
2 3 2
1 2
1 3
2 3

输出

1
3
2

方法一:floyd

floyd算法介绍:Floyd算法,也称为Floyd-Warshall算法,是一种用于寻找图中最短路径的算法。它可以处理带有负边权的图,时间复杂度为O(n^3)。Floyd算法适用于所有的有向图,但是不适用于带有负环的图。它的基本思想是动态规划,通过计算出所有点之间的最短路径,来得到整张图的最短路径。具体实现时,需要用一个二维数组来存储任意两个顶点之间的最短路径长度,再根据这个数组来计算最短路径。

#include<bits/stdc++.h>//floyd
using namespace std;
#define int long long//将所有的int 替换成long long 注意main函数要设置成signed类型
typedef long long ll;//将long long 作为(as) ll
ll N;
ll dp[405][405];//dp[u][v]=w ,包括了信息u道路到v道路的距离为w
void floyd(int n){ //floyd算法主体
	for(int i=1;i<=n;i++){
		for(int j=1;j<=n;j++){
			for(int k=1;k<=n;k++){
//				dp[i][j]=min(dp[i][j],dp[i][k]+dp[k][j]); 无法松弛i->k->k-1->j ,(i->k-1不通); 
				dp[j][k]=min(dp[j][k],dp[j][i]+dp[i][k]);//用i松弛j<->k
			}
		}
	}
}
signed main(void){
	ll M,Q; 
	cin>>N>>M>>Q;
	ll inf=1e15;//设置最大最小值还存在疑问 
	memset(dp,0x3f,sizeof dp);//初始化dp
	for(int i=0;i<M;i++){
		ll u,v,w;
		cin>>u>>v>>w;
		dp[u][v]=dp[v][u]=min(dp[u][v],w);//无向图,并且找出u<-->v的最小值
	}
	for(int i=1;i<=N;i++){
		dp[i][i]=0;//自己到自己距离为零
	}
	floyd(N);
	while(Q--){
		int st,ed;
		cin>>st>>ed;
		if(dp[st][ed]>inf) cout<<-1<<'\n';
		else cout<<dp[st][ed]<<'\n';
	}

	return 0;
}

算法主要思路是用一个点不断的去松弛其他的点,该代码中用i去松弛其他各点

Floyd算法的时间复杂度为O(n^3),适用于顶点数较少,但边数较多的图。

方法二:dijkstra

dijkstra算法介绍:Dijkstra算法是一种用于寻找图中单源最短路径的贪心算法,其时间复杂度为O(E + VlogV),其中E为边数,V为顶点数。它的基本思想是从起点开始,找到到所有其他顶点的最短路径,并标记已经找过的顶点,然后根据已找到的最短路径,选择下一个最短路径未知的顶点,不断递推下去,直到所有顶点都被标记或者找到了到达终点的最短路径。具体实现时,需要用一个数组来存储起点到每个顶点的最短路径和一个集合来存储已经找到最短路径的顶点,同时需要使用优先队列来选择下一个最短路径未知的顶点。对于边权为负数的图,Dijkstra算法是不适用的,因为它会陷入无限循环。

#include<bits/stdc++.h> 
#define int long long
using namespace std;
int st,ed,N,inf;
int dp[405][405];
long long w[405];
void dijkstra(){
	memset(w,0,sizeof(w));//初始化全为零
	int M1=N-1; 
	while(M1--){
		long long number=inf,flag=-1;
		for(int i=1;i<=N;i++){
			if(!w[i])
			if(number>dp[st][i]||flag==-1){
				number=dp[st][i];//找到最小值
				flag=i;
			}
		}
		w[flag]=1;
		for(int i=1;i<=N;i++){
			dp[st][i]=min(dp[st][i],dp[st][flag]+dp[flag][i]);//路径长度更新
		}
	}
	return ;
}
signed main(void){
	int M,Q;
	cin>>N>>M>>Q;
	memset(dp,0x3f3f,sizeof dp);//初始化
	inf=dp[0][0];//让inf=dp[0][0],使得最大值inf不存在路径是一致的
	for(int i=0;i<M;i++){
		int u,v,w;
		cin>>u>>v>>w;
		dp[u][v]=dp[v][u]=min(dp[u][v],w);
	}
	for(int i=1;i<=N;i++){
		dp[i][i]=0;
	}
     for(int i=0;i<Q;i++){
     	cin>>st>>ed;
     	dijkstra(); 
		if(dp[st][ed]>=inf) cout<<-1<<'\n';
		else cout<<dp[st][ed]<<'\n';   	
	 }	
	return 0;
}

dijkstra算法的主要思想:从起点开始,不断地找到到达离起点(st)最近的尚未访问过的节点,

循环一遍,找到最近的那个节点,该节点离起点最近,无论如何松弛都不可能更近,于是用该节点去松弛其他节点,直到最后一个未访问的节点。

有什么问题私信或者评论

题目来自蓝桥官网

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
### 回答1: C/C++算法常用手册是程序员日常工作中不可或缺的工具书之一。该手册主要收录了程序员在开发过程中常用的算法,以及相应的代码实现。该手册涵盖了诸如数据结构、排序、查找、递归、贪心、动态规划、字符串等算法,帮助程序员快速掌握这些算法的基本原理和实现方式。简单地说,该手册将算法的核心原理和实现细节集中在了一起,兼顾了易懂性和实用性。 随着程序员需求的不断增加,该手册逐渐扩充了更多的算法类型。同时,该手册还根据算法的不同应用场景进行分类,方便程序员快速查找和使用。例如,程序员可以通过该手册快速了解不同数据结构的原理和实现方法,了解常见算法的时间复杂度和空间复杂度,还可以查找常见的实际问题中的算法实现方式。 总的来说,C/C++算法常用手册是程序员必备的工具之一,帮助程序员提高算法的实现能力和解决实际问题的能力,提高程序的效率和质量。 ### 回答2: C/C++常用算法手册是一本介绍计算机算法的参考手册,主要面向C/C++语言程序员。该手册总结了各种常用的算法,包括排序、查找、图论、字符串等。通过该手册的学习,可以让程序员更好地掌握C/C++编程的技巧和方法。 该手册中介绍了排序算法,包括冒泡排序、插入排序、选择排序、快速排序、归并排序等。对于不同的排序算法,手册详细介绍了它们的思路和实现方法,同时也对它们的时间复杂度和效率进行了分析和比较。 在查找方面,手册介绍了常用的顺序查找和二分查找算法,它们可以帮助程序员快速地定位和查找数据。 在图论和字符串方面,手册介绍了很多有用的算法,如最短路径算法、最小生成树算法、字符串匹配算法等。这些算法可以帮助程序员更好地解决实际问题。 总之,C/C++常用算法手册是一本非常实用和有价值的参考书,它可以让程序员掌握更多的C/C++算法技巧,提高程序员的编程能力和开发效率。 ### 回答3: C/C++ 常用算法手册是一本总结了 C/C++ 编程语言中常用的算法、数据结构、设计模式等知识的参考书籍。 相对于其他语言,C 和 C++ 语言有着更高的执行效率和更多的编程自由度,也因此被广泛应用于开发高性能、底层的软件程序。在这样的应用场景下,对算法和数据结构的掌握显得尤为重要。 C/C++ 常用算法手册涵盖了各种基础的算法和数据结构,比如排序、查找、链表、树等。同时,它也介绍了一些常用的高级算法,比如动态规划、贪心算法和回溯算法。 此外,该手册还详细说明了面向对象编程领域中常用的设计模式和其实现方式,例如工厂模式、装饰器模式等。 阅读 C/C++ 常用算法手册不但能够让读者掌握常用算法的实现方法,更能提高编程思维和技巧。另外,在实际应用中,编写高效的程序不仅需要算法的巧妙运用,更需要细致、严谨的代码风格和设计思路。此时,该手册中丰富的示例代码和编码规范性的讲解也能为读者提供很大的帮助。 总之,C/C++ 常用算法手册是一本既实用又深入的参考书,适合广大 C/C++ 开发者和算法学习者阅读。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值