有向图最短路径的Dijsktra算法

1)包含任务或问题描述和分析

如果存在一条从i到j的最短路径(Vi.....Vk,Vj),Vk是Vj前面的一顶点。那么(Vi...Vk)也必定是从i到k的最短路径。为了求出最短路径,Dijkstra就提出了以最短路径长度递增,逐次生成最短路径的算法。譬如对于源顶点V0,首先选择其直接相邻的顶点中长度最短的顶点Vi,那么当前已知可得从V0到达Vj顶点的最短距离dist[j]=min{dist[j],dist[i]+matrix[i][j]}。根据这种思路,

假设存在G=<V,E>,源顶点为V0,U={V0},dist[i]记录V0到i的最短距离,path[i]记录从V0到i路径上的i前面的一个顶点。

1.从V-U中选择使dist[i]值最小的顶点i,将i加入到U中;

2.更新与i直接相邻顶点的dist值。(dist[j]=min{dist[j],dist[i]+matrix[i][j]})

3.直到U=V,停止。

2)设计与实现

输入一个有向图的邻接矩阵,再获取一个初始结点,找到该行邻接矩阵中的最短的路径,将其结点标记,再遍历刚标记结点的行,更新最短距离并再循环找到最小的点,直到所有的点都被标记.

3)测试例子与结果分析

测试用例:

 结果:

 4)带注释的源代码

#include<stdio.h>
#include<stdlib.h>
#define MAX_SIZE 10
#define MAXROAD 999
void Dijsktra(int g[][MAX_SIZE],int num){//num为一开始知道的结点 
   int known[MAX_SIZE]={0};
   known[num]=1;//初始化 
   int minroad[MAX_SIZE];
   int i;
   for(i=0;i<MAX_SIZE;i++){
   	minroad[i]=g[num][i];
   }
   //int prenode[MAX_SIZE]={0};
   int flag=1;//已知的结点数目 
   while(flag<MAX_SIZE){
   	int j=0,min=minroad[0];//寻找最短路中未知节点的最短路径
	for(i=0;i<MAX_SIZE;i++){
		if(known[i]==1)continue;
		if(minroad[i]<min)j=i;//寻找出最短路径的编号 
	} 
	for(i=0;i<MAX_SIZE;i++){
		if(minroad[i]>g[j][i]+minroad[j])minroad[i]=g[j][i]+minroad[j];//更新最短路径 
	}
	known[j]=1;//更新结点 
   	flag++;
   }
   	for(i=0;i<MAX_SIZE;i++){
   		if(minroad[i]!=MAXROAD)
   		printf("结点%d --->结点%d的最短路径为%d\n",num,i,minroad[i]);
	   }
	
}
int main()
{
	int Grape[MAX_SIZE][MAX_SIZE]={0};
	int i,j,num;
	printf("请输入i到j的路径并输入它的长度"); 
	while((scanf("%d%d%d",&i,&j,&num))!=EOF)
	{
		Grape[i][j]=num;
		printf("请输入i到j的路径并输入它的长度"); 
		}	
	for(i=0;i<MAX_SIZE;i++)for(j=0;j<MAX_SIZE;j++)if(Grape[i][j]==0)Grape[i][j]=MAXROAD;
	Dijsktra(Grape,0);
	
	return 0;
}

















  • 2
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值