带有负权值的单源最短路径-bellman-ford算法

本文深入探讨了Bellman-Ford算法的Java实现,详细介绍了如何处理加权图中的最短路径问题,包括边的去重、最短路径的更新以及路径的打印。此外,还讨论了如何检测图中是否存在负权回路。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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;j<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;
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值