题目
Description
给出一个有向图(无负权值),求任意两点间的最短路径
Input
第一行为有向图中点的数量n(各点从0到n-1编号)第二行为边的数量m第三行为要求其间最短路径的两个点第四行起为m条边的信息,包括起点、终点和路径长度,以空格隔开
8
15
0 5
4 5 0.35
5 4 0.35
4 7 0.37
5 7 0.28
7 5 0.28
5 1 0.32
0 4 0.38
0 2 0.26
7 3 0.39
1 3 0.29
2 7 0.34
6 2 0.40
3 6 0.52
6 0 0.58
6 4 0.93
Output
求出输入中第三行两个点之间的最短路径长度并输出,比如上面的输入例子中,点0到点5间最短路径长度为0.73,则输出为:0.73
思路
要理解这个,要有prim算法的基础会更好理解。prim算法-邻接矩阵存储的无向图最小生成树(C++/java)
一维数组dist里存储的不在是到发节点的距离,而是到初始节点的距离,每次找到最小边连着的节点,对应dist更新为父节点的dist+最小边。
java实现
import java.text.DecimalFormat;
import java.util.Scanner;
public class Dijkstra {
final static double INF = 55556.0;
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int Vnum = sc.nextInt();//顶点数
int Enum = sc.nextInt();//边数
int stare = sc.nextInt();//起始点
int end = sc.nextInt();//终点
double AdjMatrix[][] = new double[Vnum][Vnum];//邻接矩阵
for (int i = 0; i < Vnum; i++) {
for (int j = 0; j < Vnum; j++) {
AdjMatrix[i][j] = INF;
}
}
for (int i = 0; i <Enum; i++) {
int x = sc.nextInt();
int y = sc.nextInt();
double weight = sc.nextDouble();
AdjMatrix[x][y] = weight;
AdjMatrix[y][x] = weight;
}
double dist[] = new double[Vnum]; //用来记录到初始点的距离
int path[] = new int[Vnum]; //用来记录父节点是谁
int collected[] = new int[Vnum]; //用来记录节点是否收录 1表示已经收录 0表示未收录
for (int i = 0; i < Vnum; i++) {
dist[i] = AdjMatrix[stare][i];
if(dist[i]<INF){
path[i] = stare;
}else{
path[i] = -1;
}
collected[i] = 0;
}
dist[stare] = 0;
collected[stare] = 1;
while(true){
int MinV = -1,V;
double MinDist = INF;
for (V = 0; V < Vnum; V++) {
if(collected[V]==0 && dist[V]<MinDist){
MinDist = dist[V];
MinV = V;
}
}
if(MinDist==INF){
break;
}
collected[MinV] = 1;
for (int i = 0; i < Vnum; i++) {
if(collected[i]==0 && AdjMatrix[MinV][i]<INF){
if(dist[MinV]+AdjMatrix[MinV][i]<dist[i]){
dist[i] = dist[MinV]+AdjMatrix[MinV][i];
path[i] = MinV;
}
}
}
}
DecimalFormat df = new DecimalFormat("0.00");
System.out.println(df.format(dist[end]));
sc.close();
}
}
温馨提示:要提交算法题,记得将类名改为Main。