有向图最短路径的Dijkstra算法

题目介绍: 

 代码:

我们输出的是从v0点到其他点的最短路径结果,代码借鉴自这里,此文章用于自我学习。

#include<iostream>
using namespace std;
//(1)定义所需要的数组 
const int n=5; //5个点,v0-v4 
const int INF=1e7;//模拟无穷大 
int map[n][n]; //邻接矩阵 
int dis[n];//最短路径长度数组 
int path[n];//前驱数组
bool visited[n];//标记数组,1说明该顶点i已经加入到集合S,否则i属于集合V-S 

void Dijkstra(int start){
//(2)初始化源点v0到其他各个顶点的最短路径长度和前驱数组 
	for(int i=0;i<n;++i){  
		dis[i]=map[start][i]; //最短路径长度
		visited[i]=false; //所有标记置为0
		if(dis[i]<INF) //前驱数组
			path[i]=start;//说明源点u到顶点i有边相连
		else 
			path[i]=-1;//说明源点v0到顶点i无边相连
	}
//(3)初始化集合S,令集合S={start},从源点start的最短路径为0
	visited[start]=true;//将v0点标记 
	dis[start]=0;//v0到v0距离为0 
//(4)从未被标记的点里面找最小.在集合V-S中寻找距离源点v0最近的顶点t
//若找不到,则跳出循环,即结束;否则,将t加入集合S。
	for(int i=0;i<n;++i){
		
		int tmin=INF,t=start;
		for(int j=0;j<n;++j){
			if(!visited[j] && dis[j]<tmin){
				tmin=dis[j];
				t=j; //记录距离源点v0最近的顶点
			}
		}
		
		if(t==start) return ;//找不到t,结束 
		visited[t]=true; //找到,将t加入集合S
//(5)更新集合V-S中与t邻接的顶点到u的距离
		for(int j=0;j<n;++j){
			if(!visited[j] && dis[j]>(map[t][j]+dis[t]))
				dis[j]=map[t][j]+dis[t];//经过t到达j的路径更短
				path[j]=t;//记录j的前驱为t
		}
		
	}
	
	
}

int main(){
	
	for(int i=0;i<n;++i){  //初始化图的邻接矩阵 
		for(int j=0;j<n;++j){
		 	map[i][j]=INF;
		}
	}
	 
	int m,x,y,l;//边的条数,邻接矩阵的横纵坐标,边长
	cout<<"请输入边的条数:"<<endl; 
	cin>>m;
	
	while(m--) { //将边的权值输入 
		
		cin>>x>>y>>l;
		map[x][y]=l;
	}
			
	Dijkstra(0);//起点是v0点 
	
	for(int i=0;i<n;++i){  //打印结果 
		if(dis[i]<INF) 
			cout<<"v0点到v"<<i<<"点最短长度为:"<<dis[i]<<endl; 
		else	
			cout<<"无路径"<<endl; 
	} 
	
	return 0;
}

/*输入: 
7
0 1 10
0 2 12
1 3 10
2 4 7
3 0 15
3 1 12
3 4 7 
*/

输出结果:

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值