SPFA演算法求解最短路徑(改進Bellman-ford)
阿新 • • 發佈:2018-11-09
//spfa演算法步驟:https://blog.csdn.net/hehehaha1123/article/details/63250235 import java.util.*; public class SPFA { public static void main(String args[]){ Scanner in=new Scanner(System.in); while(in.hasNext()){ int Vnum=in.nextInt(); int Enum=in.nextInt(); Edge e[]=new Edge[Enum]; int start=in.nextInt(); for(int i=0;i<Enum;i++){ int flag1=1; int x=in.nextInt(); int y=in.nextInt(); int value=in.nextInt(); e[i]=new Edge(x,y,value); } int pre[]=new int[Vnum]; for(int i=0;i<Vnum;i++) pre[i]=start; int dist[]=new int[Vnum]; for(int i=0;i<Vnum;i++){ dist[i]=Integer.MAX_VALUE; } //列印結果 dist[start]=0; if(f_spfa(start,pre,dist,Vnum,e)){ for(int i=0;i<Vnum;i++){ if(i!=start) { Print_path(start,i,pre); System.out.println(dist[i]); } } } } } //spfa演算法主要步驟 public static boolean f_spfa(int start,int pre[],int dist[],int Vnum,Edge e[]){ Queue<Integer> queue=new LinkedList<Integer>(); queue.add(start); int used[]=new int[Vnum];//記錄當前是否在佇列中 int cnt[]=new int[Vnum]; //記錄使用次數 used[start]=1; cnt[start]++; while(queue.size()>0){ int pos=queue.poll(); for(int i=0;i<e.length;i++){ if(pos==e[i].x && dist[e[i].x]!=Integer.MAX_VALUE){ if(dist[e[i].x]+e[i].value<dist[e[i].y]){ pre[e[i].y]=e[i].x; dist[e[i].y]=dist[e[i].x]+e[i].value; if(used[e[i].y]==0){ queue.add(e[i].y); //入佇列策略 used[e[i].y]=1; cnt[e[i].y]++; //判斷是否有環 if(cnt[e[i].y]>Vnum){ return false; } } } } } used[pos]=0; } return true; } //列印路徑 public static void Print_path(int start,int end,int pre[]){ Stack<Integer> ans=new Stack<Integer>(); ans.add(end); while(end!=pre[end]){ end=pre[end]; ans.add(end); } int flag1=1; while(ans.size()>0) { if (flag1 == 1) { System.out.print(ans.pop()); flag1 = 0; } else { System.out.print("->" + ans.pop()); } } System.out.print("="); } } //定義資料結構 class Edge{ int x; int y; int value; Edge(int x,int y,int value){ this.x=x; this.y=y; this.value=value; } public void setValue(int value){ this.value=value; } }