贝尔曼福特算法举例

用来计算带有负权边的最短路径.

只需要对边进行N-1此松弛操作后,再对所有边进行一次松弛操作,如果最后一次没有可以松弛的边,就可以结束了.

只需要将起始点的值设置为初始值.遍历的时候,按照边的顺序遍历去松弛即可,不需要规定初始点再松弛.

如果仍旧能够结束,说明存在负环,这种情况下,如果不规定遍历次数,最短路径是无解的.

举例:2240:Arbitrage

代码:

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.*;

public class Main {
public static void main(String[] args) throws Exception {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st;
int caseCnt = 0;
while(true){
caseCnt++;
st = new StringTokenizer(br.readLine());
int n = Integer.parseInt(st.nextToken());
if(n == 0)
{
break;
}
List nameList = new ArrayList();
for(int i = 0;i<n;i++){
st = new StringTokenizer(br.readLine());
nameList.add(st.nextToken());
}

        st = new StringTokenizer(br.readLine());
        int exchangeCnt = Integer.parseInt(st.nextToken());
        int start;
        int end;
        double rate;
        Object[][] conn = new Object[exchangeCnt][3];
        for(int i =0;i<exchangeCnt;i++){
            st = new StringTokenizer(br.readLine());
            start = nameList.indexOf(st.nextToken());
            rate = Double.parseDouble(st.nextToken());
            end = nameList.indexOf(st.nextToken());
            conn[i] = new Object[]{start,end,rate};
        }
        Object[][] visitedInfo = new Object[n][2];

        double[] visited = new double[n];
        visited[0] = 10000;
        Object[] visitPoint;
        for(int i = 0;i<n;i++){
            for(int j = 0;j<exchangeCnt;j++){
                visitPoint = conn[j];
                if(Double.compare(visited[(int)visitPoint[1]],visited[(int)visitPoint[0]]*(double)visitPoint[2])<0){
                    visited[(int)visitPoint[1]] = visited[(int)visitPoint[0]]*(double)visitPoint[2];
                }
            }
        }
        boolean result = false;
        for(int j = 0;j<exchangeCnt;j++){
            visitPoint = conn[j];
            if(Double.compare(visited[(int)visitPoint[1]],visited[(int)visitPoint[0]]*(double)visitPoint[2])<0){
                result = true;
            }
        }
        if(result){
            System.out.println("Case "+caseCnt+": "+"Yes");
        }
        else{
            System.out.println("Case "+caseCnt+": "+"No");
        }
        st = new StringTokenizer(br.readLine());
    }
}

}

posted @ 2021-04-30 16:46  Monstro  阅读(185)  评论(0)    收藏  举报