最短路径算法实现

关于最短路径的一个简单模板,错误应该会很多,望大家指正

最短路径的步骤

dis数组记录源点到定点的最短距离 例如:源点为0 dis[1]=6 即0-》1最短距离为6
pre数组用于记录路径,从终点往源点有,值记录先驱
1找出源点距离哪个点最近,然后记录最近距离,记录最近点下标,将这个点加入已访问数组。
2.接下来将这个点作为!中介点!,遍历所有顶点,判断是否
顶点未被访问且中介点能到该点且中介点到该点+源点到中介点的距离小于源点到该点的距离
3.满足这三个条件后需要将dis数组内的到该点的值进行替换,pre记录该点的先驱为中介点
4.完成这一过程后,会找到源点距离最近的一个点,且将最近点进入最近集合,n个点循环n次,将dis数组的值完全更新后,即可得出源点到指定地点的最短距离
主要还是在判断部分,如果集合内的中介点b到c比 源点a到c 距离更近,更新
在这里插入图片描述
##代码

#include<bits/stdc++.h>
using namespace std;
const int INF = 0x3f3f3f3f;
int map1[100][100];
int dis[100];//点到远点的距离
int visited[100]; 
int pre[100];
int n,m,s,d;
void Dijie()
{
   
	//dis给初值 
	for(int i=0;i<n;i++){
		if(s==i) dis[i]=0;
		else dis[i]=map1[s][i];
	}
	while(1){
   	  int k=-1;
	 visited[s]=1;
	 int min1=INF;
	 //找最小值,在与已知集合相连的点中找 
	 for(int i=0;i<n;i++){
	 	if(!visited[i]&&min1>dis[i]){
	 		k=i;
	 		min1=dis[i];
	 	}
	 } 
	 if(k==-1) break;
	 visited[k]=1;
	 //找到当前最短集合以外的一个最小路径点 
	 for(int v=0;v<n;v++){
	 	if(!visited[v]&&map1[k][v]!=INF&&dis[v]>dis[k]+map1[k][v]){
	 		dis[v]=dis[k]+map1[k][v];
	 		pre[v]=k;
	 	}
	 }
    }
}
void print_path(){
	while(pre[d]!=d){
		cout<<d<<"->";
		d=pre[d];
	}
}
int main()
{
	int x,y,z;
	cin>>n>>m>>s>>d;
	memset(map1,INF,sizeof(map1));
	memset(dis,INF,sizeof(dis));
	memset(visited,0,sizeof(visited));
	for(int i=0;i<20;i++){
		pre[i]=i;
	}
	for(int i=0;i<m;i++){
		cin>>x>>y>>z;
		map1[x][y]=z;
		map1[y][x]=z; 
	}
	Dijie();
	print_path();
	for(int i=0;i<10;i++)
	  cout<<pre[i]<<" ";
}
/*
测试 0到 5的最短路径 
6 8 0 5
0 1 1
0 3 4
0 4 4
1 3 2
3 2 2
2 5 1
4 5 3
3 4 3
*/
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值