package dataStructures;
public class Dijkstra {
/**
* Dijkstra求单源点最短路径
* 原理:首先引入一个辅助向量D,他的每个分量D[i]表示当前所找到的从v到每个中点的最短路径的长度。他的初态:若从v到
* vi有弧,则D[i]为弧上的权重;否则D[i]为正无穷。显然,长度为D[j]=Min{D[i]|i属于V}的路径是从v出发的长度最短的
* 一条最短路径。此路径为(v,vj).
* 那么,吓一条长度次短的路径是那一条?假设次短路径的重点是vk,则可想而知,这条路径或者是(v,vk),或者是(v,vj,vk)。
* 他的长度或者是从v到vk的弧上的权重,或者是D[j]和vj到vk弧上的权重之和。所以可以递归的求解从v0到各个节点的所有最
* 短路径。
* @param graph
* @param v0
* @param n
*/
public static void findShortestPath_DIJ(int [][] graph,int v0,int n){
int [] D=new int[n];//用于存放v0到vi的最短路径值
boolean [] finish=new boolean[n];//是否加入S
int [] pre=new int[n];//存放到vi最短路径的上一个节点
int NOValue=Integer.MAX_VALUE,NOPre=-1,NOLink=0;
for(int i=0;i<n;i++){//初始化
if(graph[v0][i]!=NOLink){
D[i]=graph[v0][i];
pre[i]=v0;
}else{
D[i]=NOValue;
pre[i]=NOPre;
}
finish[i]=false;
}
//对起始节点初始化
finish[v0]=true;
pre[v0]=NOPre;
D[v0]=NOValue;
for(int i=0;i<n-1;i++){//进行n-1次循环,找出n-1条最短路径
//找出V-S中最小的j
int minj=-1,minValue=Integer.MAX_VALUE;
for(int j=0;j<n;j++){
if(!finish[j]){
if(D[j]<minValue){
minj=j;
minValue=D[j];
}
}
}
//输出该最短路径
if(minj!=-1){
System.out.print("最短路径一条:<"+v0+","+minj+">="+minValue+"||path="+minj);
int count=minj;
while(pre[count]!=NOPre){
// System.out.println("count1="+count);
System.out.print(" "+pre[count]);
count=pre[count];
// System.out.println("count2="+count);
}
System.out.println();
}else{
System.out.println("不再存在从v0可到达的最短路径");
break;
}
//更新D,pre,finish
finish[minj]=true;
for(int j=0;j<n;j++){
if(!finish[j]){
if(graph[minj][j]!=NOLink&&(D[minj]+graph[minj][j])<D[j]){
pre[j]=minj;
D[j]=D[minj]+graph[minj][j];
}
}
}
}
}
public static void main(String [] args){
int [][] graph={
{0,0,10,0,30,100},
{0,0,5,0,0,0},
{0,0,0,50,0,0},
{0,0,0,0,0,10},
{0,0,0,20,0,60},
{0,0,0,0,0,0}
};
Dijkstra.findShortestPath_DIJ(graph, 0, 6);
}
}