拓撲排序+最短路徑(無環加權有向圖最短路徑演算法)
阿新 • • 發佈:2018-12-31
特點:
1、線性時間內解決單點最短路徑問題
2、能夠處理負權邊問題
3、能夠找出最長路徑
不足:因為是基於拓撲排序的,所以不能解決帶環的問題
import java.util.ArrayList; import java.util.Scanner; import java.util.Stack; import Graph.HasCycle; public class TopDij { static boolean[]visit; static boolean[]onStack; static Stack<Integer> stack; static int n, m; static boolean hasCycle = false; static int[]dis; static int INF = 99999999; static ArrayList<EdgeS> []adj; public static void main(String[] args) { Scanner in = new Scanner(System.in); n = in.nextInt(); m = in.nextInt(); visit = new boolean[n+1]; adj = new ArrayList[n+1]; stack = new Stack<>(); dis = new int[n+1]; onStack = new boolean[n+1]; for(int i = 1; i <= n; i++ ) { adj[i] = new ArrayList<>(); } for(int i = 0; i < m; i++ ) { int from = in.nextInt(); int to = in.nextInt(); int w = in.nextInt(); adj[from].add(new EdgeS(from, to, w)); } bfs(1); // while(!stack.isEmpty()) { // System.out.println(stack.pop() + " "); // } if(!hasCycle) { shortPath(1); for(int i = 1; i <= n; i++ ) { System.out.println(dis[i] + " "); } } else { System.out.println("hasCycle"); } } public static void shortPath(int s) { for(int i = 1; i <= n; i++ ) { dis[i] = 99999999; } dis[s] = 0; while(!stack.isEmpty()) { int cur = stack.pop(); for(EdgeS e: adj[cur]) { if(dis[e.to] > dis[cur] + e.w) { dis[e.to] = dis[cur] + e.w; } } } } public static void bfs(int cur) {// 進行拓撲排序的同時檢查是否含有環 有環的話就退出 visit[cur] = true; onStack[cur] = true; for(EdgeS e:adj[cur]) { if(!visit[e.to]) { bfs(e.to); } else if(onStack[e.to]){ hasCycle = true; return; } } onStack[cur] = false; stack.push(cur);//記錄拓撲排序結果 、逆後序 } } class EdgeS{ int from, to, w; public EdgeS(int f, int t, int w) { from = f; to = t; this.w = w; } }