Floyd : City of Blinding Lights

  • + 0 comments
    1. Anyone who' doing it in java and using djisktra algo, it is possible.
    2. Store the Graph in Hashmap , edges as well.
    3. Store distances in hashmap
    4. Use priority queue
    5. Make a Node class for priority queue
    6. Store the results in hashmap
    7. In the main code, where reading of file is going on, start coding right from there so you don't have to iterate the loop again.
    8. There are multiple edges. You have to save the latest entry.
    9. If the source and distance is same return 0.
    10. Run till priority is not empty or destination source is reached.
    11. I used recursion.
    12. It took me a week to solve as I did not clear priority queue for each new query.
    13. So clear distances hashmap, queue etc before going for next query.
    14. Heres the code, but please try it yourself, it took me a week, you can do it too.
    15. 15.
    import java.io.*;
    import java.math.*;
    import java.security.*;
    import java.text.*;
    import java.util.*;
    import java.util.concurrent.*;
    import java.util.function.*;
    import java.util.regex.*;
    import java.util.stream.*;
    import static java.util.stream.Collectors.joining;
    import static java.util.stream.Collectors.toList;
    
    
    public class Solution {
        static PriorityQueue<Node> nodesToVisit = new PriorityQueue<>();
        
        static class Node implements Comparable<Node> {
            int vertex;
            int distance = 0;
            boolean visited = false;
    
            public Node(int vertex, int distance) {
                // vertexes.
                this.vertex = vertex;
                this.distance = distance;
            }
            @Override
            public int compareTo(Node other) {
                return Integer.compare(this.distance, other.distance);
            }
            @Override
            public boolean equals(Object obj) {
                if (this == obj) return true;
                if (obj == null || getClass() != obj.getClass()) return false;
                Node node = (Node) obj;
                return vertex == node.vertex;
            }
            @Override
            public int hashCode() {
                return Objects.hash(vertex);
            }
            @Override
            public String toString() {
                return "{ Node : "+vertex+" Distance is: "+distance+" }";
            }
        }
        static HashMap<List<Integer>, Integer> results = new HashMap<>();
        static  HashMap<Integer,HashMap<Integer,Integer>> adjacencyList2 = new HashMap<>();
        static HashSet<Integer> visited;
    
        public static int shortestPathFinder(int sourceVertex, int destination ){
            int weight=0;// weight of current node
            if(sourceVertex == destination) return distance.get(sourceVertex);
            if (!visited.contains(sourceVertex))         
            {   
                weight = distance.get(sourceVertex); // weight of the source
    
                for (Map.Entry<Integer,Integer> edgeWithWeight : adjacencyList2.get(sourceVertex).entrySet()) {
                //key is edge(neighbour) of source and value is the weight of the edge
                // updating distances to all neighbours
                    weight += edgeWithWeight.getValue(); // weight of negihbour edge 
                    
                    int neighbourExistingWeight = 300000;
                    if (distance.containsKey(edgeWithWeight.getKey())) neighbourExistingWeight = distance.get(edgeWithWeight.getKey());
    
                    if (neighbourExistingWeight > weight) { // neighrbour ka existing weight check
                        distance.put(edgeWithWeight.getKey(),weight);
                        Node node = new Node(edgeWithWeight.getKey(), distance.get(edgeWithWeight.getKey()));
                        // if (nodesToVisit.contains(node)) {
                            // nodesToVisit.remove(node);
                        // }
                        nodesToVisit.add(node);  
                    }
                    weight = distance.get(sourceVertex); // weight of the source
    
                }
            }
            visited.add(sourceVertex);
            if (nodesToVisit.isEmpty()) return -1;
    
            return shortestPathFinder(nodesToVisit.remove().vertex, destination);
        }
        
        
        static HashMap<Integer, Integer> distance = new HashMap<>();
        public static void main(String[] args) throws IOException {
            BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(System.in));
    
            String[] roadNodesEdges = bufferedReader.readLine().replaceAll("\\s+$", "").split(" ");
    
            int roadNodes = Integer.parseInt(roadNodesEdges[0]);
            int roadEdges = Integer.parseInt(roadNodesEdges[1]);
    
            // List<Integer> roadFrom = new ArrayList<>();
            // List<Integer> roadTo = new ArrayList<>();
            // List<Integer> roadWeight = new ArrayList<>();
    
            // int startNode, endNode, weight;
            IntStream.range(0, roadEdges).forEach(i -> {
                try {
                    String[] roadFromToWeight = bufferedReader.readLine().replaceAll("\\s+$", "").split(" ");
    
                    // roadFrom.add(Integer.parseInt(roadFromToWeight[0]));
                    // roadTo.add(Integer.parseInt(roadFromToWeight[1]));
                    // roadWeight.add(Integer.parseInt(roadFromToWeight[2]));
                    int startNode = Integer.parseInt(roadFromToWeight[0]);
                    int endNode = Integer.parseInt(roadFromToWeight[1]);
                    int weight = Integer.parseInt(roadFromToWeight[2]);
           
                    HashMap<Integer,Integer> edgesAndWeight = new HashMap<>();
                    edgesAndWeight.put(endNode, weight);
                    if (adjacencyList2.containsKey(startNode)) {
                        edgesAndWeight = adjacencyList2.get(startNode);
                        edgesAndWeight.put(endNode, weight);
                                    
                    }else{
                        adjacencyList2.put(startNode, edgesAndWeight);
                    }
                    if (!adjacencyList2.containsKey(endNode)) {              
                        adjacencyList2.put(endNode, new HashMap<>());
                    }
                } catch (IOException ex) {
                    throw new RuntimeException(ex);
                }
            });
            // System.out.println(adjacencyList2);
            int q = Integer.parseInt(bufferedReader.readLine().trim());
    
            HashMap<List<Integer>, Integer> results = new HashMap<>(); 
            IntStream.range(0, q).forEach(qItr -> {
                try 
                {
                    String[] firstMultipleInput = bufferedReader.readLine().replaceAll("\\s+$", "").split(" ");
    
                    int x = Integer.parseInt(firstMultipleInput[0]);
    
                    int y = Integer.parseInt(firstMultipleInput[1]);
                    List<Integer> k = new ArrayList<Integer>(); // query pair
                    k.add(x);
                    k.add(y);
                    int startNode = x;
                    int endNode = y;
                    int shortestPath = -1;
                    if (results.containsKey(k)) {
                        System.out.println(results.get(k));
                    }else 
                    if(startNode == endNode) System.out.println(0);
                    else{
                     
                        visited = new HashSet<>();
                        distance.clear();
                        nodesToVisit.clear();
                        //above is to clear any useless data and start new for new query
                        distance.put(startNode,0);
                        shortestPath = shortestPathFinder(startNode,endNode);
                        System.out.println(shortestPath);
                        results.put(k, shortestPath);
                    }
                } catch (IOException ex) {
                    throw new RuntimeException(ex);
                }
            });
            bufferedReader.close();
        }
    }