最短路径问题---Dijkstra算法详解

https://blog.csdn.net/qq_35644234/article/details/60870719#t1
各种不同语言实现迪杰斯特拉算法,实现单源最短路径问题

一、算法的实现

1. pascal语言

type
bool=array[1…10]ofboolean;
arr=array[0…10]ofinteger;
var
a:array[1…10,1…10]ofinteger;//存储图的邻接数组,无边为10000
c,d,e:arr;//c为最短路径数值,d为各点前趋,
t:bool;//e:路径,t为辅助数组
i,j,n,m:integer;
inf,outf:text;
procedureinit;//不同题目邻接数组建立方式不一样
begin
assign(inf,inputfile);
assign(outf,outputfile);
reset(inf);
rewrite(outf);
read(inf,n);
fori:=1tondo
begin
forj:=1tondo
begin
read(inf,a[i,j]);
ifa[i,j]=0then
a[i,j]:=10000;
end;
end;
end;
proceduredijkstra(qi:integer;t:bool;varc{,d}:arr);
//qi起点,{}中为求路径部分,不需求路径时可以不要
var
i,j,k,min:integer;
begin
t[qi]:=true;
//t数组一般在调用前初始,除起点外所有节点都化成false,也可将部分点初始化成true以回避这些点
fori:=1tondo
d[i]:=qi;
d[qi]:=0;
fori:=1tondo
c[i]:=a[qi,i];
fori:=1ton-1do
begin
min:=maxint;//改为最大值
forj:=1tondo
if(c[j]<min)andnott[j]then
begin
k:=j;
min:=c[j];
end;
t[k]:=true;
forj:=1tondo
if(c[k]+a[k,j]<c[j])andnott[j]then
begin
c[j]:=c[k]+a[k,j];
d[j]:=k;
end;
end;
end;
proceduremake(zh:integer;d:arr;vare:arr);//生成路径,e[0]保存路径
var
i,j,k:integer;//上的节点个数
begin
i:=0;
whiled[zh]<>0do
begin
inc(i);
e[i]:=zh;
zh:=d[zh];
end;
inc(i);
e[i]:=qi;
e[0]:=i;
end;
主程序调用:求长度:初始化t,然后dijkstra(qi,t,c,d)
求路径:make(m,d,e) ,m是终点

2. java语言

//初始化路径,都为最大值。
intpath[][]=newint[n+1][n+1];
for(inti=1;i<n+1;i++){
for(intj=1;j<n+1;j++)
path[i][j]=Integer.MAX_VALUE;
}
//这里需要输入path[i][j]的具体内容,如果有重复数据的话,需要更新路径为最小值。
intminLen[]=newint[n+1];
//visit初始为0,防止回溯
intvisit[]=newint[n+1];
//初始化1到其他点的距离。
for(inti=1;i<n+1;i++){
minLen[i]=path[1][i];
}
voidDijkstra(){
minLen[1]=0;
visit[1]=1;
intminj=1;
for(inti=1;i<n+1;i++){
intmin=Integer.MAX_VALUE;
for(intj=1;j<n+1;j++){
if(visit[j]==0&&minLen[j]<min){
min=minLen[j];
minj=j;
}
}
visit[minj]=1;
for(intj=1;j<n+1;j++){
if(visit[j]==0&&minLen[minj]!=Integer.MAX_VALUE&&path[minj][j]!=
Integer.MAX_VALUE&&minLen[j]>(minLen[minj]+path[minj][j])){
minLen[j]=minLen[minj]+path[minj][j];
}
}
}
}

3. C语言

#include<stdio.h>
#include<stdlib.h>
#define max 11000000000
inta[1000][1000];
intd[1000];//d表示某特定边距离
intp[1000];//p表示永久边距离
inti,j,k;
intm;//m代表边数
intn;//n代表点数
intmain()
{
scanf("%d%d",&n,&m);
intmin1;
intx,y,z;
for(i=1;i<=m;i++)
{
scanf("%d%d%d",&x,&y,&z);
a[x][y]=z;
a[y][x]=z;
}
for(i=1;i<=n;i++)
d[i]=max1;
d[1]=0;
for(i=1;i<=n;i++)
{
min1=max1;
for(j=1;j<=n;j++)
if(!p[j]&&d[j]<min1)
{
min1=d[j];
k=j;
}
p[k]=j;
for(j=1;j<=n;j++)
if(a[k][j]!=0&&!p[j]&&d[j]>d[k]+a[k][j])
d[j]=d[k]+a[k][j];
}
for(i=1;i<n;i++)
printf("%d->",p[i]);
printf("%d\n",p[n]);
return0;
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值