这里写自定义目录标题
问题描述
给定一个带权有向图 G=(V,E) ,其中每条边的权是一个非负实数。另外,还给定 V 中的一个顶点,称为源。现在我们要计算从源到所有其他各顶点的最短路径长度。这里的长度是指路上各边权之和。这个问题通常称为单源最短路径问题。
Dijkstra算法的解决方案
Dijkstra提出按各顶点与源点v间的路径长度的递增次序,生成到各顶点的最短路径的算法。既先求出长度最短的一条最短路径,再参照它求出长度次短的一条最短路径,依次类推,直到从源点v 到其它各顶点的最短路径全部求出为止。
源码:
public final static int maxint=10000;
private static void run(int n,int v,int dist[],int prev[],int c[][]) {
boolean s[]=new boolean[maxint];
for(int i=1;i<=n;i++) {
dist[i]=c[v][i];
s[i]=false;
if(dist[i]==maxint) prev[i]=0;
else prev[i]=v;
}
dist[v]=0;s[v]=true;
for(int i=1;i<n;i++) {
int temp=maxint;
int u=v;
for(int j=1;j<=n;j++)
if((!s[j])&&(dist[j]<temp)) {u=j;temp=dist[j];}
s[u]=true;
for(int j=1;j<=n;j++)
if((!s[j])&&(c[u][j]<maxint)) {
int newdist=dist[u]+c[u][j];
if(newdist<dist[j]) { dist[j]=newdist;prev[j]=u; }
}
}
}
private static void 递归(int x,int prev[]) {
if(x==1) ;
else { 递归(prev[x],prev);System.out.print( prev[x]+"--->");
}
}
private static void 最短路径(int x,int prev[],int c[][]) {
System.out.print(x+"的最短单源路径为:");
递归(x,prev);
System.out.println(x);
}
public static void main(String args[]) {
int n=6;
int v=1;
int dist[]=new int[6];
int prev[]=new int[6]; // 0 1 2 3 4 5
int c[][]=new int[][]{ /*0*/ {0, 0 , 0 , 0 , 0 , 0 },
/*1*/ {0, 0 , 10 ,maxint, 30 , 100 },
/*2*/ {0,maxint, 0 , 50 ,maxint,maxint},
/*3*/ {0,maxint,maxint, 0 ,maxint, 10 },
/*4*/ {0,maxint,maxint, 20 , 0 , 60 },
/*5*/ {0,maxint,maxint,maxint,maxint, 0 }
};
run(n-1,1,dist,prev,c);
for(int i=2;i<n;i++) {
最短路径(i,prev,c);
System.out.println(i+"的最短单源路径长度为:"+dist[i]);
System.out.println();
}
}