帶有負權值的單源最短路徑-bellman-ford演算法
阿新 • • 發佈:2018-11-09
https://baike.baidu.com/item/Bellman-Ford%E7%AE%97%E6%B3%95/1089090?fr=aladdin&fromid=6039406&fromtitle=bellman-ford 參考百科的c++實現版本 import java.util.*; public class Bellman_Ford { public static void main(String args[]){ Scanner in=new Scanner(System.in); while(in.hasNext()){ int Vnum=in.nextInt(); int Enum=in.nextInt(); List<Edge> E=new ArrayList<Edge>(); //輸入資料 for(int i=0;i<Enum;i++){ int x=in.nextInt(); int y=in.nextInt(); int value=in.nextInt(); int flag1=1; //對邊進行去重 for(int j=0;i<E.size();j++){ Edge temp1=E.get(j); if(x==temp1.x && y==temp1.y){ if(temp1.value>value){ E.get(j).setValue(value); flag1=0; break; } } } if(flag1==1){ E.add(new Edge(x,y,value)); } } int pre[]=new int[Vnum]; int dist[]=new int[Vnum]; if(Bellman(0,pre,E,dist,Vnum)){ for(int i=1;i<Vnum;i++){ Print_path(0,i,pre); System.out.println("="+dist[i]); } } } } public static boolean Bellman(int start,int pre[],List<Edge> E,int dist[],int Vnum){ int MAX=Integer.MAX_VALUE; for(int i=0;i<Vnum;i++){ dist[i]=MAX; } dist[start]=0; for(int i=0;i<Vnum-1;i++){ for(int j=0;j<E.size();j++){ Edge temp2=E.get(j); if(dist[temp2.x]!=MAX){ if(dist[temp2.x]+ temp2.value<dist[temp2.y]){ dist[temp2.y]=dist[temp2.x]+temp2.value; //更新最短路徑 pre[temp2.y]=temp2.x; //儲存路徑前驅 } } } } //判斷是否有負權迴路 boolean flag2=true; for(int i=0;i<E.size();i++){ Edge temp3=E.get(i); if(dist[temp3.x]!=MAX){ if(dist[temp3.x]+ temp3.value<dist[temp3.y]){ flag2=false; break; } } } return flag2; } //列印路徑函式 public static void Print_path(int start,int end,int pre[]){ Stack<Integer> path=new Stack<Integer>(); path.push(end); int root=end; while(root!=pre[root]){ root=pre[root]; path.push(root); } int flag3=1; while(path.size()>0){ if(flag3==1){ System.out.print(path.pop()); flag3=0; }else{ System.out.print("->"+path.pop()); } } } } //定義資料結構 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; } }