图论基础算法
Dijkstra
Dijkstra朴素版:将图中的点分为两个集合,一个集合为已经找到最短距离的点,另一个集合为还没有找到最短距离的点。初始化一个dis数组,dis[i]表示源点到i点的最短距离。外层循环n次,每次将一个点加入找到最短距离的集合。内层循环每次在未找到最短距离的集合中找到当前集合中距离源点最近的点,并用当前点去尝试更新其他点的最短距离。
代码:
import java.util.Scanner;
public class Main{
static int n,m,INF = 0x3f3f3f3f;
static int[][] g = new int[550][550];
static boolean[] flag = new boolean[550];
public static void main(String[] args){
Scanner sc = new Scanner(System.in);
n = sc.nextInt();
m = sc.nextInt();
for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) if(i!=j) g[i][j] = INF;
for(int i=0;i<m;i++){
int x = sc.nextInt();
int y = sc.nextInt();
int z = sc.nextInt();
g[x][y] = Math.min(g[x][y],z);
}
int res = fun();
System.out.println(res);
}
public static int fun(){
int[] dis = new int[n+5];
for(int i=1;i<=n;i++) dis[i] = INF;
dis[1] = 0;
for(int i=0;i<n;i++){
int t = -1;
for(int j=1;j<=n;j++){
if(!flag[j]&&(t==-1||dis[t]>dis[j])) t = j;
}
flag[t] = true;
for(int j=1;j<=n;j++) dis[j] = Math.min(dis[j],dis[t]+g[t][j]);
}
return dis[n]==INF?-1:dis[n];
}
}
Dijkstra堆优化版本:采用优先队列优化,每次弹出距离源点最短距离的点,判断这个点是不是已经找到最短距离,如果已经找到了,忽略,否则用其更新他所能到的点,并将被更新的点加入队列。
代码:
import java.util.PriorityQueue;
import java.util.Scanner;
public class Main{
static int index,n,m,INF=0x3f3f3f3f;
static boolean[] flag = new boolean[200000];
static int[] node = new int[200000],list = new int[200000],next = new int[200000],value = new int[200000];
public static void main(String[] args){
Scanner sc = new Scanner(System.in);
n = sc.nextInt();
m = sc.nextInt();
for(int i=1;i<=n;i++) list[i] = -1;
for(int i=0;i<m;i++){
int x = sc.nextInt();
int y = sc.nextInt();
int z = sc.nextInt();
add(x,y,z);
}
int res = fun();
System.out.println(res);
}
public static int fun(){
PriorityQueue<Node> queue = new PriorityQueue<>();
queue.add(new Node(1,0));
int[] dis = new int[n+5];
for(int i=1;i<=n;i++) dis[i] = INF;
dis[1] = 0;
while(queue.size()>0){
Node no = queue.poll();
int id = no.id;
int ds= no.dis;
if(flag[id]) continue;
flag[id] = true;
for(int i=list[id];i!=-1;i=next[i]){
if(value[i]+dis[id]<dis[node[i]]){
dis[node[i]] = value[i]+dis[id];
queue.add(new Node(node[i],dis[node[i]]));
}
}
}
return dis[n]>=INF/2?-1:dis[n];
}
public static void add(int a,int b,int c){
node[index] = b;
next[index] = list[a];
value[index]= c;
list[a] = index++;
}
}
class Node implements Comparable<Node>{
int id,dis;
public Node(int id, int dis) {
this.id = id;
this.dis = dis;
}
public int compareTo(Node o) {
return this.dis-o.dis;
}
}