79 lines
1.8 KiB
Java
79 lines
1.8 KiB
Java
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]);
|
|
}
|
|
}
|