programming-examples/java/Data_Structures/DijkstraSegmentTree.java

79 lines
1.8 KiB
Java
Raw Normal View History

2019-11-15 12:59:38 +01:00
import java.util.*;
import java.util.stream.Stream;
public class DijkstraSegmentTree {
public static void shortestPaths(List<Edge>[] edges, int s, long[] prio, int[] pred) {
Arrays.fill(pred, -1);
Arrays.fill(prio, Long.MAX_VALUE);
prio[s] = 0;
long[] t = new long[edges.length * 2];
Arrays.fill(t, Long.MAX_VALUE);
set(t, s, 0);
while (true) {
int cur = minIndex(t);
if (t[cur + t.length / 2] == Long.MAX_VALUE)
break;
set(t, cur, Long.MAX_VALUE);
for (Edge e : edges[cur]) {
int v = e.t;
long nprio = prio[cur] + e.cost;
if (prio[v] > nprio) {
prio[v] = nprio;
pred[v] = cur;
set(t, v, nprio);
}
}
}
}
public static class Edge {
int t;
int cost;
public Edge(int t, int cost) {
this.t = t;
this.cost = cost;
}
}
static void set(long[] t, int i, long value) {
i += t.length / 2;
if (t[i] < value && value != Long.MAX_VALUE)
return;
t[i] = value;
for (; i > 1; i >>= 1)
t[i >> 1] = Math.min(t[i], t[i ^ 1]);
}
static int minIndex(long[] t) {
int res = 1;
while (res < t.length / 2)
res = res * 2 + (t[res * 2] > t[1] ? 1 : 0);
return res - t.length / 2;
}
// Usage example
public static void main(String[] args) {
int[][] cost = {{0, 3, 2}, {0, 0, -2}, {0, 0, 0}};
int n = cost.length;
List<Edge>[] edges = Stream.generate(ArrayList::new).limit(n).toArray(List[]::new);
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
if (cost[i][j] != 0) {
edges[i].add(new Edge(j, cost[i][j]));
}
}
}
long[] dist = new long[n];
int[] pred = new int[n];
shortestPaths(edges, 0, dist, pred);
System.out.println(0 == dist[0]);
System.out.println(3 == dist[1]);
System.out.println(1 == dist[2]);
System.out.println(-1 == pred[0]);
System.out.println(0 == pred[1]);
System.out.println(1 == pred[2]);
}
}