Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- package graph;
- import java.io.File;
- import java.io.IOException;
- import java.util.ArrayDeque;
- import java.util.ArrayList;
- import java.util.Arrays;
- import java.util.Comparator;
- import java.util.Deque;
- import java.util.HashMap;
- import java.util.List;
- import java.util.Map;
- import java.util.PriorityQueue;
- import java.util.stream.Collectors;
- import java.io.BufferedReader;
- import java.io.BufferedWriter;
- import java.io.File;
- import java.io.IOException;
- import java.io.InputStreamReader;
- import java.io.OutputStreamWriter;
- import java.util.StringTokenizer;
- import java.io.FileReader;
- import java.math.BigDecimal;
- import java.math.BigInteger;
- class OptimizedScanner {
- private BufferedReader br;
- private StringTokenizer st;
- public OptimizedScanner() {
- br = new BufferedReader(new InputStreamReader(System.in));
- }
- public OptimizedScanner(File file) throws IOException {
- br = new BufferedReader(new FileReader(file));
- }
- public boolean ready() throws IOException {
- return (br.ready() || st.hasMoreTokens());
- }
- public String next() {
- while (st == null || !st.hasMoreTokens()) {
- try {
- st = new StringTokenizer(br.readLine());
- } catch (IOException e) {
- e.printStackTrace();
- }
- }
- return st.nextToken();
- }
- public int nextInt() {
- return Integer.parseInt(next());
- }
- public long nextLong() {
- return Long.parseLong(next());
- }
- public void close() {
- try {
- br.close();
- } catch (IOException e) {
- e.printStackTrace();
- }
- }
- }
- class OptimizedWriter {
- private BufferedWriter bw;
- public OptimizedWriter() {
- bw = new BufferedWriter(new OutputStreamWriter(System.out));
- }
- public <T> void write(T value) {
- try {
- bw.write(value.toString());
- } catch (IOException e) {
- e.printStackTrace();
- }
- }
- public <T> void writeln(T value) {
- try {
- bw.write(value.toString());
- bw.write('\n');
- } catch (IOException e) {
- e.printStackTrace();
- }
- }
- public <T> void writeNext(T value) {
- write(value);
- write(' ');
- }
- public <T> void writeIterable(Iterable<T> iterable) {
- for (T item : iterable) {
- writeNext(item);
- }
- write('\n');
- }
- public void writelnArray(byte[] array) {
- for (byte item : array) {
- writeNext(item);
- }
- write('\n');
- }
- public void writelnArray(short[] array) {
- for (short item : array) {
- writeNext(item);
- }
- write('\n');
- }
- public void writelnArray(int[] array) {
- for (int item : array) {
- writeNext(item);
- }
- write('\n');
- }
- public void writelnArray(long[] array) {
- for (long item : array) {
- writeNext(item);
- }
- write('\n');
- }
- public void writelnArray(float[] array) {
- for (float item : array) {
- writeNext(item);
- }
- write('\n');
- }
- public void writelnArray(double[] array) {
- for (double item : array) {
- writeNext(item);
- }
- write('\n');
- }
- public void writelnArray(char[] array) {
- for (char item : array) {
- writeNext(item);
- }
- write('\n');
- }
- public void writelnArray(boolean[] array) {
- for (boolean item : array) {
- writeNext(item);
- }
- write('\n');
- }
- public void writelnArray(BigInteger[] array) {
- for (BigInteger item : array) {
- writeNext(item);
- }
- write('\n');
- }
- public void writelnArray(BigDecimal[] array) {
- for (BigDecimal item : array) {
- writeNext(item);
- }
- write('\n');
- }
- public void close() {
- try {
- bw.flush();
- bw.close();
- } catch (IOException e) {
- e.printStackTrace();
- }
- }
- }
- public class ProblemE {
- public static void main(String[] args) {
- // OptimizedScanner scanner = new OptimizedScanner();
- File file = new File("graph_input_e.txt");
- OptimizedScanner scanner = null;
- OptimizedWriter writer = new OptimizedWriter();
- try {
- scanner = new OptimizedScanner(file);
- } catch (IOException e) {
- e.printStackTrace();
- }
- int n = scanner.nextInt();
- List<Integer> prep_time = new ArrayList<>();
- List<Integer> speeds = new ArrayList<>();
- int[][] roads = new int[n][n];
- for (int i = 0; i < n; i++) {
- for (int j = 0; j < n; j++) {
- if (i != j) {
- roads[i][j] = -1;
- }
- }
- }
- for (int i = 0; i < n; i++) {
- int t = scanner.nextInt();
- int v = scanner.nextInt();
- prep_time.add(t);
- speeds.add(v);
- }
- for (int i = 0; i < n - 1; i++) {
- int a = scanner.nextInt();
- int b = scanner.nextInt();
- int s = scanner.nextInt();
- roads[a - 1][b - 1] = s;
- roads[b - 1][a - 1] = s;
- }
- List<List<Pair<Integer, Double>>> full_graph = new ArrayList<>();
- for (int i = 0; i < n; i++) {
- full_graph.add(new ArrayList<>());
- }
- for (int city = 1; city < n; city++) {
- full_graph.set(city, bfs(roads, city, speeds, prep_time));
- }
- double latest_time = 0;
- int[] latest_path = null;
- // for (int i = 0; i < full_graph.size(); i++) {
- // for (int j = 0; j < full_graph.get(i).size(); j++) {
- // Pair <Integer, Double> pair = full_graph.get(i).get(j);
- // System.out.println((i + 1) + " to " + (pair.getKey() + 1) + ": " + pair.getValue());
- // }
- // }
- for (int city = 0; city < 1; city++) {
- Pair<Double, int[]> result = dijkstra(full_graph, city);
- double travel_time = result.getKey();
- int[] path = result.getValue();
- if (travel_time > latest_time) {
- latest_time = travel_time;
- latest_path = path;
- }
- }
- writer.writeln(String.format("%.10f", latest_time));
- for (int city : latest_path) {
- writer.writeNext(city);
- }
- scanner.close();
- writer.close();
- }
- public static List<Pair<Integer, Double>> bfs(int[][] roads, int city, List<Integer> speeds, List<Integer> prepTime) {
- Map<Integer, Double> distances = new HashMap<>();
- distances.put(city, 0.0);
- Deque<Pair<Double, Integer>> queue = new ArrayDeque<>();
- queue.add(new Pair<>(0.0, city));
- while (!queue.isEmpty()) {
- Pair<Double, Integer> pair = queue.poll();
- double time = pair.getKey();
- int currentCity = pair.getValue();
- if (currentCity == 0) {
- break;
- }
- for (int i = 0; i < roads[currentCity].length; i++) {
- int targetCity = i;
- int roadLength = roads[currentCity][i];
- if (currentCity == targetCity || roadLength == -1)
- continue;
- double newTime = time + roadLength;
- if (!distances.containsKey(targetCity) || newTime < distances.get(targetCity)) {
- distances.put(targetCity, newTime);
- queue.add(new Pair<>(newTime, targetCity));
- }
- }
- }
- List<Pair<Integer, Double>> result = new ArrayList<>();
- for (Map.Entry<Integer, Double> entry : distances.entrySet()) {
- int target = entry.getKey();
- double travelTime = entry.getValue() / speeds.get(city) + prepTime.get(city);
- if (target != city) {
- result.add(new Pair<>(target, travelTime));
- }
- }
- return result;
- }
- public static Pair<Double, int[]> dijkstra(List<List<Pair<Integer, Double>>> graph, int start) {
- int n = graph.size();
- double[] distance = new double[n];
- Arrays.fill(distance, Double.POSITIVE_INFINITY);
- // distance[start] = 0.0;
- PriorityQueue<Pair<Double, Integer>> queue = new PriorityQueue<>((a, b) -> Double.compare(a.getKey(), b.getKey()));
- queue.offer(new Pair<Double, Integer>(0.0, start));
- int[] paths = new int[n];
- Arrays.fill(paths, -1);
- boolean[] visited = new boolean[n];
- while (!queue.isEmpty()) {
- Pair<Double, Integer> curr = queue.poll();
- double dist = curr.getKey();
- int current = curr.getValue();
- if (visited[current]) {
- continue;
- }
- visited[current] = true;
- // if (current == n - 1) {
- // break;
- // }
- for (int i = 0; i < graph.size(); i++) {
- if (!graph.get(i).isEmpty() && current < graph.get(i).size()) {
- Pair<Integer, Double> neighbor = graph.get(i).get(current);
- int neighborIndex = neighbor.getKey();
- double weight = neighbor.getValue();
- dist = distance[neighborIndex];
- dist = (dist == Double.POSITIVE_INFINITY) ? 0.0 : dist;
- // System.out.println("Current: " + (current + 1) + ", i: " + (i + 1) + ", neighborIndex: " + (neighborIndex + 1));
- //
- // System.out.println("From " + (neighborIndex + 1) + " to " + (i + 1) + ", weight: " + weight);
- // System.out.println(dist + " + " + weight + " < " + distance[i]);
- if (dist + weight < distance[i]) {
- distance[i] = dist + weight;
- paths[i] = neighborIndex;
- queue.offer(new Pair<Double, Integer>(distance[i], i));
- }
- }
- }
- }
- double maxDistance = Double.NEGATIVE_INFINITY;
- int maxDistanceCity = -1;
- for (int i = 1; i < n; i++) {
- if (distance[i] > maxDistance)
- maxDistanceCity = i;
- maxDistance = Math.max(distance[i], maxDistance);
- }
- // System.out.println("Max: " + maxDistanceCity + ", Distance: " + maxDistance);
- List<Integer> maxDistancePath = new ArrayList<>();
- int current = maxDistanceCity;
- while (current != -1) {
- maxDistancePath.add(current + 1);
- current = paths[current];
- }
- int[] result = new int[maxDistancePath.size()];
- for (int i = 0; i < maxDistancePath.size(); i++) {
- result[i] = maxDistancePath.get(i);
- }
- return new Pair<Double, int[]>(maxDistance, result);
- }
- static class Pair<K, V> {
- private K key;
- private V value;
- public Pair(K key, V value) {
- this.key = key;
- this.value = value;
- }
- public K getKey() {
- return key;
- }
- public V getValue() {
- return value;
- }
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment