贝尔曼福特算法举例
用来计算带有负权边的最短路径.
只需要对边进行N-1此松弛操作后,再对所有边进行一次松弛操作,如果最后一次没有可以松弛的边,就可以结束了.
只需要将起始点的值设置为初始值.遍历的时候,按照边的顺序遍历去松弛即可,不需要规定初始点再松弛.
如果仍旧能够结束,说明存在负环,这种情况下,如果不规定遍历次数,最短路径是无解的.
代码:
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
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());
}
}
}

浙公网安备 33010602011771号