package com.xjj.lanqiao;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.Scanner;
import javax.swing.plaf.metal.MetalIconFactory.FolderIcon16;
/*-----求-单源最短路-的SPFA算法-----
* 1.给定的图存在负权边,这时类似Dijkstra等算法便没有了用武之地,而Bellman-Ford算法的复杂度又过高,
* 2.设立一个先进先出的队列q用来保存待优化的结点,优化时每次取出队首结点u,
* 并且用u点当前的最短路径估计值对离开u点所指向的结点v进行松弛操作,
* 如果v点的最短路径估计值有所调整,且v点不在当前的队列中,就将v点放入队尾。
* 这样不断从队列中取出结点来进行松弛操作,直至队列空为止。
*
* 3.dis[j]>dis[i]+w[i,j]
*
* 4.样例输入
3 3
1 2 -1
1 3 2
2 3 -1
样例输出
-1
-2
*
* 5.此为邻接链表实现
* 6.必须将带求节点放在第一个
* */
public class Spfa {
//邻接表的形式创建图
static class edge{
public int start;
public int end;
public int value;
public edge(int a, int b, int value) {
start = a;
end = b;
this.value = value;
}
}
//spfa算法
public static void spfa(ArrayList<edge>[] lists, int n){
//dis[i]
long[] dis = new long[n+1];
for(int i = 1; i <= n; i++)
dis[i] = Integer.MAX_VALUE;
//自己到自己为0
dis[1] = 0;
//创建队列, 队列用来保存待优化的结点,优化时每次取出队首结点u
LinkedList<Integer> list = new LinkedList<>();
list.add(1);
//判断队列是否为空
while(list.size() > 0){
//取队首元素,对其他边的权值
int start = list.getFirst();
for(int i = 0; i < lists[start].size(); i++){
int end = lists[start].get(i).end;
int value = lists[start].get(i).value;
//将start作为中介,松弛
if (dis[end] > dis[start] + value) {
dis[end] = dis[start] + value;
if (!list.contains(end)) {
list.add(end);
}
}
}
list.removeFirst();
}
//到其他顶点
for(int i = 2; i < n+1; i++)
System.out.println(dis[i]);
}
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
//List<ArrayList<edge>> lists = new ArrayList<>();
//ArrayList<edge> list = new ArrayList<>();
//n = 节点数,m = 边数
int n = scanner.nextInt();
int m = scanner.nextInt();
//告诉编译器忽略指定的警告,不用在编译完成后出现警告信息。
@SuppressWarnings("unchecked")
ArrayList<edge>[] list = new ArrayList[n+1];
//以数组的形式
for(int i = 1; i <= n; i++)
list[i] = new ArrayList<edge>();
for(int i = 1; i <= m; i++){
int a = scanner.nextInt();
int b = scanner.nextInt();
int value = scanner.nextInt();
//当a相同时,类似:1 2 -1, 1 3 2; size为2
list[a].add(new edge(a, b, value));
//lists.add(list);
}
spfa(list, n);
}
}
单源最短路--SPFA算法--邻接链表
最新推荐文章于 2019-06-04 20:26:02 发布