Pagini recente » Cod sursa (job #828101) | Cod sursa (job #591744) | Cod sursa (job #383559) | Cod sursa (job #980929) | Cod sursa (job #2230074)
import java.io.*;
import java.util.*;
public class Main {
public static void main(String[] args) throws IOException {
InputStream inputStream = new FileInputStream("dijkstra.in");
OutputStream outputStream = new FileOutputStream("dijkstra.out");
try (InputReader inputReader = new InputReader(inputStream);
PrintWriter printWriter = new PrintWriter(outputStream)) {
int numberNodes = inputReader.nextInt();
int numberEdges = inputReader.nextInt();
Graph graph = new Graph(numberNodes);
for (int edge = 0; edge < numberEdges; edge++) {
int from = inputReader.nextInt();
int to = inputReader.nextInt();
int cost = inputReader.nextInt();
graph.addEdge(from, to, cost);
}
int[] distancesFromNodeOne = Dijkstra.runFromNode(1, graph);
for (int i = 2; i <= numberNodes; i++) {
printWriter.print(distancesFromNodeOne[i] + " ");
}
}
}
static class Dijkstra {
private static final Integer INF = Integer.MAX_VALUE >> 1;
public static int[] runFromNode(int source, Graph graph) {
Heap minHeap = new Heap(graph.getNumberOfNodes());
minHeap.update(source, 0);
// only simple paths make sense. they can have length at most N - 1
for (int totalSteps = 1; totalSteps < graph.getNumberOfNodes(); totalSteps++) {
int bestNode = minHeap.poll();
int currNodeCost = minHeap.getCostForNode(bestNode);
for (Graph.Edge edge : graph.getEdges(bestNode)) {
int newEstimate = currNodeCost + edge.cost;
if (minHeap.getCostForNode(edge.to) > newEstimate) {
minHeap.update(edge.to, newEstimate);
}
}
}
int[] costToNode = minHeap.getCostPerNodes();
// map unreachable nodes to 0 (required by the caller)
for (int i = 1; i <= graph.getNumberOfNodes(); i++) {
if (costToNode[i] == INF) {
costToNode[i] = 0;
}
}
return costToNode;
}
}
static class Heap {
private int N;
private int[] heapOrderedByNode;
private int[] costPerNode;
private int[] posForNodeInHeap;
public Heap(int N) {
this.N = N;
this.costPerNode = new int[N + 1];
this.posForNodeInHeap = new int[N + 1];
Arrays.fill(costPerNode, Dijkstra.INF);
heapOrderedByNode = new int[N + 1];
for (int node = 1; node <= N; node++) {
heapOrderedByNode[node] = node;
posForNodeInHeap[node] = node;
costPerNode[node] = Dijkstra.INF;
}
}
public int poll() {
int rootNode = heapOrderedByNode[1];
swapPositions(1, N);
N--;
updateDownstream(1);
return rootNode;
}
public int getCostForNode(int node) {
return costPerNode[node];
}
public boolean cmpPositions(int firstPos, int secondPos) {
return costPerNode[heapOrderedByNode[firstPos]] < costPerNode[heapOrderedByNode[secondPos]];
}
public void swap(int[] arr, int pos1, int pos2) {
int aux = arr[pos1];
arr[pos1] = arr[pos2];
arr[pos2] = aux;
}
public void swapPositions(int firstPos, int secondPos) {
posForNodeInHeap[heapOrderedByNode[firstPos]] = secondPos;
posForNodeInHeap[heapOrderedByNode[secondPos]] = firstPos;
swap(heapOrderedByNode, firstPos, secondPos);
}
private void updateUpstream(int pos) {
if (pos <= 1) {
return ;
}
while (pos / 2 >= 1 && cmpPositions(pos, pos / 2)) {
swapPositions(pos, pos / 2);
pos /= 2;
}
}
private void updateDownstream(int pos) {
int bestChild;
while (2 * pos <= N) {
bestChild = 2 * pos;
if (2 * pos + 1 <= N && cmpPositions(2 * pos + 1, bestChild)) {
bestChild = 2 * pos + 1;
}
if (!cmpPositions(bestChild, pos)) {
break;
}
swapPositions(pos, bestChild);
pos = bestChild;
}
}
public void update(int node, int newEstimate) {
costPerNode[node] = newEstimate;
int positionInHeap = posForNodeInHeap[node];
if (positionInHeap > 1 && cmpPositions(positionInHeap, positionInHeap / 2)) {
updateUpstream(positionInHeap);
} else {
updateDownstream(positionInHeap);
}
}
public int[] getCostPerNodes() {
return costPerNode;
}
}
static class Graph {
private int N;
private List<List<Edge>> edges;
public Graph(int numberOfNodes) {
this.N = numberOfNodes;
edges = new ArrayList<>(N + 1);
for (int node = 0; node <= N; node++) {
edges.add(new LinkedList<>());
}
}
public void addEdge(int from, int to, int cost) {
edges.get(from).add(new Edge(to, cost));
}
public int getNumberOfNodes() {
return N;
}
public List<Edge> getEdges(int node) {
return edges.get(node);
}
static class Edge {
private int to;
private int cost;
public Edge(int to, int cost) {
this.to = to;
this.cost = cost;
}
}
}
static class InputReader implements AutoCloseable {
private BufferedReader bufferedReader;
private StringTokenizer stringTokenizer;
public InputReader(InputStream inputStream) {
bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
stringTokenizer = null;
}
private String nextToken() {
if (stringTokenizer == null || !stringTokenizer.hasMoreTokens()) {
try {
stringTokenizer = new StringTokenizer(bufferedReader.readLine());
} catch (IOException e) {
throw new RuntimeException(e);
}
}
return stringTokenizer.nextToken();
}
public int nextInt() {
return Integer.parseInt(nextToken());
}
@Override
public void close() throws IOException {
bufferedReader.close();
}
}
}