在寻找加权无向图中的最小生成树的Prim算法:构造最小生成树每一步都向这棵树中添加一条新的边。Dijkstra算法采用了类似的方法计算最短路径树。
关于Prim算法可点击下方链接进行了解。
算法过程
这里我们以3为源点出发,这里的顶点同意表示为vi(顶点3表示v3):
同时把v3标记为已经使用过
按照此步骤局部进行:
与下方的输出结合观察,更能直观的了解其过程:
Code
import java.util.*;
import java.io.*;
public class Dijkstra {
public static final int INF=1000;//定义一个无限距离,当两个顶点之间不存在连接且无权值设置为INF
public static int V;//顶点个数
public static int cost[][];//cost[v][u]表示从顶点v到顶点u的权值
public static boolean used[];//顶点是否已被使用
public static int d[];//从一个顶点v出发的最短距离
public static void main(String[] args) {
Scanner in = new Scanner(new BufferedInputStream(System.in));
while (in.hasNext()) {
V=in.nextInt();
System.out.println("Vertex number: "+V);//顶点个数
//初始化
cost=new int[V][V];
used=new boolean[V];
d=new int[V];
for (int i = 0; i < V; i++) {
Arrays.fill(cost[i],INF);
}
//输入数据
//顶点之间的边赋值 输入为0 0 0 时退出
while (true){
int v0=in.nextInt();//顶点1
int v1=in.nextInt();//顶点2
int c=in.nextInt();//顶点之间权值
if(v0==0&&v1 == 0&&c == 0){
System.out.println("Done");
break;
}
cost[v0][v1]=c;
cost[v1][v0]=c;
System.out.println(v0+" - "+v1+" cost:"+c);
}
int v=in.nextInt();
System.out.println("Source: "+v);
dijkstra(v);
int sum=0;
for (int i = 0; i < V; i++) {
sum+=d[i];
System.out.println(v+" - "+i+" cost:"+d[i]);
}
System.out.println("Total cost: "+sum);
}
}
//从顶点v开始dijkstra算法
public static void dijkstra(int v){
//初始化
Arrays.fill(d,INF);//先将所有点都离散开来
Arrays.fill(used,false);
d[v]=0;//从顶点v出发
while (true) {
int v1=-1;
//从尚未使用过的顶点中选择一个最小的顶点
for (int i = 0; i < V; i++) {
if(!used[i]&&(v1==-1||d[i]<d[v1])){
v1=i;
}
}
if(v1==-1){
System.out.println("Done");
break;
}
used[v1]=true;
System.out.println(v1+" is used");
for (int i = 0; i < V; i++) {
d[i]=Math.min(d[i],d[v1]+cost[v1][i]);
}
}
}
}
Input
7
0 2 5
0 1 2
1 2 4
2 3 2
1 3 6
1 4 10
4 5 3
3 5 1
4 6 5
5 6 9
0 0 0
3
Output
Vertex number: 7
0 - 2 cost:5
0 - 1 cost:2
1 - 2 cost:4
2 - 3 cost:2
1 - 3 cost:6
1 - 4 cost:10
4 - 5 cost:3
3 - 5 cost:1
4 - 6 cost:5
5 - 6 cost:9
Done
Source: 3
3 is used
5 is used
2 is used
4 is used
1 is used
0 is used
6 is used
Done
3 - 0 cost:7
3 - 1 cost:6
3 - 2 cost:2
3 - 3 cost:0
3 - 4 cost:4
3 - 5 cost:1
3 - 6 cost:9
Total cost: 29
例题HDU2544
题目链接:
hdu2544https://vjudge.net/problem/HDU-2544
使用优先队列和结构体:
package graph;
import java.util.*;
public class hdu2544 {
static int n, m;
static final int INF = 1000000;
static List<edge> e[];
/**
* 定义结构体
*/
static class edge {
int from;
int to;
int w;
public edge(int from, int to, int w) {
this.from = from;
this.to = to;
this.w = w;
}
}
static class pair {
int id;
int dis;
/**
* @param id 节点
* @param dis 此节点到起点的距离
*/
public pair(int id, int dis) {
this.id = id;
this.dis = dis;
}
}
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
while (sc.hasNext()) {
n = sc.nextInt();
m = sc.nextInt();
if (n == 0 && m == 0) break;
e = new List[n + 1];
for (int i = 0; i <= n; i++) {
e[i] = new ArrayList<>();
}
while (m-- > 0) {
int from = sc.nextInt();
int to = sc.nextInt();
int w = sc.nextInt();
e[from].add(new edge(from, to, w));
e[to].add(new edge(to, from, w));
}
dijkstra();
}
}
static void dijkstra() {
int s = 1;
int dis[] = new int[n + 1];
boolean v[] = new boolean[n + 1];
//初始化
Arrays.fill(dis, INF);
Arrays.fill(v, false);
dis[s] = 0;//起点到自己的距离为0
//定义优先队列
PriorityQueue<pair> Q = new PriorityQueue<>(
new Comparator<pair>() {
@Override
public int compare(pair o1, pair o2) {
return o1.dis - o2.dis;
}
}
);
Q.add(new pair(s, dis[s]));
while (!Q.isEmpty()) {
pair cur = Q.poll();
if (v[cur.id]) continue;
v[cur.id] = true;
for (int i = 0; i < e[cur.id].size(); i++) {
edge t = e[cur.id].get(i);
if (v[t.to]) continue;
if (dis[t.to] > t.w + cur.dis) {
dis[t.to] = t.w + cur.dis;
Q.add(new pair(t.to, dis[t.to]));
}
}
}
System.out.println(dis[n]);
}
}
提交结果: