1.题目
给定带权有向图G=(V,E,W),以及源点v∈V,求从v点出发到达其它顶点的最短路径。
2.思路
1)设集合S中的顶点为当前已经找到最短路径的顶点。
初始:S={v},当S=V时算法结束。
2)将从源点v到顶点u且只经过集合S中顶点的路径称为: 从v到u相对于S集合的最短路径。
dist[u]: 从v到u相对于S集合的最短路径长度;
short[u]: 从v到u全局最短的路径长度
Dijkstra算法的核心思想就是先用贪心选择求出dist[u], 然后不断的扩充S集合从而刷新dist数组的值,即dist[u]会越来越靠近最优解short[u]。当S=V时,dist = short
3.代码
class mGraph {
char[] vertexs; // 顶点集合
int[][] matrix; // 邻接矩阵
}
public class GS_Dijkstra {
//传入源点 、顶点总数 与 带权有向图G
private static final int INF = Integer.MAX_VALUE; // 最大值
void Dijkstra(Graph g,int v,int n){
boolean[] s = new boolean[n];
int[] dist = new int[n];
int[] prev = new int[n];
//1.初始化
for(int i=0;i<n;i++){
dist[i] = g.matrix[v][i]; //拿到源点v到其它n个顶点的距离
s[i] = false;
if(dist[i] == INF) //当v到i没有边时
prev[i] = -1; //i前驱节点标记为-1
else
prev[i] = v;
}
for(int i=0;i<n;i++){
int min = INF;
int u = -1;
//2.在V-S集合中找到dist最小的j,并将其加入S
for(int j=0;j<n;j++){
if(!s[j] && dist[j]<min){//当j号顶点未被加入S集合 并且 v到j的距离在当前遍历的顶点中最小
u = j;
min = dist[j]; //记录距离和顶点下标
}
}
s[u] = true; //加入S集合
System.out.println(g.vertexs[prev[u]]+"顶点到"+g.vertexs[u]+"顶点的距离为:"+dist[u]);
//3.根据新加入S集合的顶点来修改dist数组 (只针对V-S中的顶点)
for(int j=0;j<n;j++){
if(!s[i]){
int newdist = dist[u] + g.matrix[u][j];
if(newdist < dist[j]){
dist[j] = newdist;
prev[j] = u;
}
}
}
}
}
}