文章目录
- [Bellman_ford 队列优化算法(又名SPFA)卡码网 94. 城市间货物运输 I](#Bellman_ford 队列优化算法(又名SPFA)卡码网 94. 城市间货物运输 I)
- [bellman_ford之判断负权回路 卡码网 95. 城市间货物运输 I](#bellman_ford之判断负权回路 卡码网 95. 城市间货物运输 I)
- [bellman_ford之单源有限最短路 卡码网 96. 城市间货物运输 III](#bellman_ford之单源有限最短路 卡码网 96. 城市间货物运输 III)
Bellman_ford 队列优化算法(又名SPFA)卡码网 94. 城市间货物运输 I
使用队列来优化。
java
import java.util.*;
class Edge {
int to;
int val;
Edge(int to, int val) {
this.to = to;
this.val = val;
}
}
class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
int m = sc.nextInt();
List<List<Edge>> grid = new ArrayList<>();
for (int i = 0; i <= n; i++) {
grid.add(new ArrayList<>());
}
for (int i = 0; i < m; i++) {
int s = sc.nextInt();
int t = sc.nextInt();
int val = sc.nextInt();
grid.get(s).add(new Edge(t, val));
}
boolean[] inque = new boolean[n + 1];
int[] minDist = new int[n + 1];
Arrays.fill(minDist, Integer.MAX_VALUE);
minDist[1] = 0;
Queue<Integer> dq = new LinkedList<>();
dq.add(1);
inque[1] = true;
while(!dq.isEmpty()) {
int cur = dq.poll();
inque[cur] = false;
for (Edge edge : grid.get(cur)) {
if (minDist[edge.to] > minDist[cur] + edge.val) {
minDist[edge.to] = minDist[cur] + edge.val;
if (!inque[edge.to]) {
dq.add(edge.to);
inque[edge.to] = true;
}
}
}
}
if (minDist[n] == Integer.MAX_VALUE) {
System.out.println("unconnected");
}
else {
System.out.println(minDist[n]);
}
}
}
bellman_ford之判断负权回路 卡码网 95. 城市间货物运输 I
判断是否一个节点真正的入队了n次,从而判断是否成环。
java
import java.util.*;
class Edge {
int to;
int val;
Edge(int to, int val) {
this.to = to;
this.val = val;
}
}
class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
int m = sc.nextInt();
List<List<Edge>> grid = new ArrayList<>();
for (int i = 0; i <= n; i++) {
grid.add(new ArrayList<>());
}
for (int i = 0; i < m; i++) {
int s = sc.nextInt();
int t = sc.nextInt();
int val = sc.nextInt();
grid.get(s).add(new Edge(t, val));
}
boolean[] inque = new boolean[n + 1];
int[] minDist = new int[n + 1];
Arrays.fill(minDist, Integer.MAX_VALUE);
minDist[1] = 0;
Queue<Integer> dq = new LinkedList<>();
dq.add(1);
inque[1] = true;
boolean flag = false;
int[] count = new int[n + 1];
while(!dq.isEmpty()) {
int cur = dq.poll();
inque[cur] = false;
for (Edge edge : grid.get(cur)) {
if (minDist[edge.to] > minDist[cur] + edge.val) {
minDist[edge.to] = minDist[cur] + edge.val;
if (!inque[edge.to]) {
dq.add(edge.to);
inque[edge.to] = true;
count[edge.to]++;
}
if (count[edge.to] >= n) {
flag = true;
while (!dq.isEmpty()) dq.poll();
break;
}
}
}
}
if (flag) {
System.out.println("circle");
} else if (minDist[n] == Integer.MAX_VALUE) {
System.out.println("unconnected");
} else {
System.out.println(minDist[n]);
}
}
}
bellman_ford之单源有限最短路 卡码网 96. 城市间货物运输 III
从原点开始松弛边,松弛一次能找到距离原点1条边的最短路径,k个点就需要松弛k + 1边。
java
import java.util.*;
class Edge {
int from;
int to;
int val;
Edge(int from, int to, int val) {
this.from = from;
this.to = to;
this.val = val;
}
}
class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
int m = sc.nextInt();
List<Edge> grid = new ArrayList<>();
for (int i = 0; i < m; i++) {
int s = sc.nextInt();
int t = sc.nextInt();
int val =sc.nextInt();
grid.add(new Edge(s,t,val));
}
int src = sc.nextInt();
int dst = sc.nextInt();
int k = sc.nextInt();
int[] minDist = new int[n + 1];
Arrays.fill(minDist, Integer.MAX_VALUE);
int[] copyDist = new int[n + 1];
minDist[src] = 0;
for (int i =0; i < k + 1; i++) {
copyDist = Arrays.copyOf(minDist, n + 1);
for (Edge edge : grid) {
if (copyDist[edge.from] != Integer.MAX_VALUE && minDist[edge.to] > copyDist[edge.from] + edge.val) {
minDist[edge.to] = copyDist[edge.from] + edge.val;
}
}
}
if (minDist[dst] == Integer.MAX_VALUE) {
System.out.println("unreachable");
} else {
System.out.println(minDist[dst]);
}
}
}