├── A-Star ├── A star │ └── DistWithCoords.java └── Bidirectional A-Star │ └── DistWithCoords.java ├── Bidirectional Dijkstra └── FriendSuggestion.java ├── Contraction Hierarchies └── DistPreprocessSmall.java ├── LICENSE └── README.md /A-Star/A star/DistWithCoords.java: -------------------------------------------------------------------------------- 1 | //Program to Implement A-Start Agorithm. 2 | 3 | import java.util.Scanner; 4 | import java.util.ArrayList; 5 | import java.util.Arrays; 6 | import java.util.PriorityQueue; 7 | import java.lang.Math; 8 | 9 | public class DistWithCoords { 10 | //class for a Vertex in the Graph. 11 | static class Vertex{ 12 | int vertexNum; //id of the vertex. 13 | int x; //x co-ordinate of the vertex. 14 | int y; //y co-ordinate of the vertex. 15 | long distance; //distance of the vertex from the source. 16 | long potential; //euclidean distance of the vertex and target vertex. 17 | long distwithPotential; //combining i.e suming distance and potential. 18 | int queuePos; //pos of the vertex in the PriorityQueue. 19 | boolean processed; //check if the vertex is processed while traversing the graph. 20 | ArrayList adjList; //list of adjacent vertices from this vertex. 21 | ArrayList costList; //list of costs or distances of adjacent vertices from this vertex. 22 | 23 | public Vertex(){ 24 | } 25 | 26 | public Vertex(int vertexNum, int x, int y){ 27 | this.vertexNum=vertexNum; 28 | this.x=x; 29 | this.y=y; 30 | this.adjList=new ArrayList(); 31 | this.costList=new ArrayList(); 32 | } 33 | 34 | } 35 | 36 | //Implementing PriorityQueue data structure by myself for this program. (using Min-Heap property.) 37 | static class PriorityQueue{ 38 | //function to swap elements int the priorityQ. 39 | public void swap(Vertex [] graph, int [] priorityQ, int index1, int index2){ 40 | int temp = priorityQ[index1]; 41 | 42 | priorityQ[index1]=priorityQ[index2]; 43 | graph[priorityQ[index2]].queuePos=index1; 44 | 45 | priorityQ[index2]=temp; 46 | graph[temp].queuePos=index2; 47 | } 48 | 49 | //function to swap the source vertex with the first element in the priorityQ. 50 | public void makeQueue(Vertex [] graph,int [] forwpriorityQ, int source, int target){ 51 | swap(graph, forwpriorityQ,0,source); 52 | } 53 | 54 | //function to extract the min element from the priorityQ. based on the distwithPotential attribute. 55 | public int extractMin(Vertex [] graph, int [] priorityQ, int extractNum){ 56 | int vertex = priorityQ[0]; 57 | int size = priorityQ.length-1-extractNum; 58 | swap(graph,priorityQ,0,size); 59 | siftDown(0,graph,priorityQ,size); 60 | return vertex; 61 | } 62 | 63 | //function to siftdown the element at the given index in the priorityQ. 64 | public void siftDown(int index, Vertex [] graph, int [] priorityQ, int size){ 65 | int min = index; 66 | if(2*index+1 graph[priorityQ[2*index+1]].distwithPotential){ 67 | min = 2*index+1; 68 | } 69 | if(2*index+2 graph[priorityQ[2*index+2]].distwithPotential){ 70 | min = 2*index+2; 71 | } 72 | if(min!=index){ 73 | swap(graph,priorityQ,min,index); 74 | siftDown(min,graph,priorityQ,size); 75 | } 76 | } 77 | 78 | //function to change the priority of an element in the priorityQ. (priority can only decrease). 79 | public void changePriority(Vertex [] graph, int [] priorityQ, int index){ 80 | if((index-1)/2 > -1 && graph[priorityQ[index]].distwithPotential < graph[priorityQ[(index-1)/2]].distwithPotential){ 81 | swap(graph,priorityQ,index,(index-1)/2); 82 | changePriority(graph,priorityQ,(index-1)/2); 83 | } 84 | } 85 | } 86 | 87 | 88 | //function to calculate the euclidean distance between two vertices. 89 | private static long calcPotential(Vertex [] graph, int vertex1, int vertex2){ 90 | long potential = (long)Math.sqrt(Math.pow((graph[vertex1].x - graph[vertex2].x),2) + Math.pow((graph[vertex1].y - graph[vertex2].y),2)); 91 | return potential; 92 | } 93 | 94 | //function to initialize the graph. 95 | public static void initialize(Vertex [] graph, int [] forwpriorityQ, int source, int target){ 96 | for(int i=0;i vertexList = graph[vertex].adjList; 115 | ArrayList costList = graph[vertex].costList; 116 | graph[vertex].processed = true; 117 | 118 | for(int i=0;i graph[vertex].distance + cost){ 123 | graph[temp].distance = graph[vertex].distance + cost; 124 | graph[temp].distwithPotential = graph[temp].distance + graph[temp].potential; 125 | queue.changePriority(graph,priorityQ,graph[temp].queuePos); 126 | } 127 | } 128 | } 129 | 130 | 131 | //function to compute the distance between soure and the target. 132 | public static long computeDist(Vertex [] graph, int source, int target){ 133 | //create priorityQ. 134 | int [] forwpriorityQ = new int[graph.length]; 135 | 136 | //initialize the graph. 137 | initialize(graph,forwpriorityQ,source,target); 138 | 139 | PriorityQueue queue = new PriorityQueue(); 140 | queue.makeQueue(graph, forwpriorityQ,source,target); 141 | 142 | for(int i=0;i adjList; //list of adjacent vertices from this vertex. 22 | ArrayList costList; //list of costs or distances of adjacent vertices from this vertex. 23 | 24 | public Vertex(){ 25 | } 26 | 27 | public Vertex(int vertexNum, int x, int y){ 28 | this.vertexNum=vertexNum; 29 | this.x=x; 30 | this.y=y; 31 | this.adjList=new ArrayList(); 32 | this.costList=new ArrayList(); 33 | } 34 | 35 | } 36 | 37 | 38 | //Implemented PriorityQueue Data Structure by myself.(using Min-Heap Property) 39 | static class PriorityQueue{ 40 | //function to swap values in the priorityQ. 41 | public void swap(Vertex [] graph, int [] priorityQ, int index1, int index2){ 42 | int temp = priorityQ[index1]; 43 | 44 | priorityQ[index1]=priorityQ[index2]; 45 | graph[priorityQ[index2]].queuePos=index1; 46 | 47 | priorityQ[index2]=temp; 48 | graph[temp].queuePos=index2; 49 | } 50 | 51 | //function to swap source vertex with the first vertex int he priorityQ. 52 | public void makeQueue(Vertex [] graph, Vertex [] reverseGraph, int [] forwpriorityQ, int [] revpriorityQ, int source, int target){ 53 | swap(graph, forwpriorityQ,0,source); 54 | swap(reverseGraph, revpriorityQ,0,target); 55 | } 56 | 57 | //function to extract the vertex with min distwithpotential value from the PriorityQueue. 58 | public int extractMin(Vertex [] graph, int [] priorityQ, int extractNum){ 59 | int vertex = priorityQ[0]; 60 | int size = priorityQ.length-1-extractNum; 61 | swap(graph,priorityQ,0,size); 62 | siftDown(0,graph,priorityQ,size); 63 | return vertex; 64 | } 65 | 66 | 67 | //function to siftdown the vertex in the priotityQ. 68 | public void siftDown(int index, Vertex [] graph, int [] priorityQ, int size){ 69 | int min = index; 70 | if(2*index+1 graph[priorityQ[2*index+1]].distwithPotential){ 71 | min = 2*index+1; 72 | } 73 | if(2*index+2 graph[priorityQ[2*index+2]].distwithPotential){ 74 | min = 2*index+2; 75 | } 76 | if(min!=index){ 77 | swap(graph,priorityQ,min,index); 78 | siftDown(min,graph,priorityQ,size); 79 | } 80 | } 81 | 82 | //function to change the prirority of a vertex. (can only decrease the priority). 83 | public void changePriority(Vertex [] graph, int [] priorityQ, int index){ 84 | if((index-1)/2 > -1 && graph[priorityQ[index]].distwithPotential < graph[priorityQ[(index-1)/2]].distwithPotential){ 85 | swap(graph,priorityQ,index,(index-1)/2); 86 | changePriority(graph,priorityQ,(index-1)/2); 87 | } 88 | } 89 | } 90 | 91 | 92 | //function to calculate the potential of the vertex i.e euclidean distance between two vertices. 93 | private static long calcPotential(Vertex [] graph, int vertex1, int vertex2){ 94 | long potential = (long)Math.sqrt(Math.pow((graph[vertex1].x - graph[vertex2].x),2) + Math.pow((graph[vertex1].y - graph[vertex2].y),2)); 95 | return potential; 96 | } 97 | 98 | 99 | //function to initialize the graph. 100 | public static void initialize(Vertex [] graph, Vertex [] reverseGraph, int [] forwpriorityQ, int [] revpriorityQ, int source, int target){ 101 | for(int i=0;i vertexList = graph[vertex].adjList; 126 | ArrayList costList = graph[vertex].costList; 127 | graph[vertex].processed = true; 128 | 129 | for(int i=0;i graph[vertex].distance + cost){ 134 | graph[temp].distance = graph[vertex].distance + cost; 135 | graph[temp].distwithPotential = graph[temp].distance + graph[temp].potential ; 136 | queue.changePriority(graph,priorityQ,graph[temp].queuePos); 137 | } 138 | } 139 | } 140 | 141 | 142 | //function to find the correct distance of the vertex. 143 | public static void correctDistance(Vertex [] graph, Vertex [] reverseGraph, int vertex, long correctDist){ 144 | if(graph[vertex].distance == Long.MAX_VALUE || reverseGraph[vertex].distance == Long.MAX_VALUE){ 145 | return; 146 | } 147 | if(correctDist>graph[vertex].distance + reverseGraph[vertex].distance){ 148 | correctDist = graph[vertex].distance + reverseGraph[vertex].distance; 149 | } 150 | } 151 | 152 | //function to compute the distance between the source vertex and the target vertex. 153 | public static long computeDist(Vertex [] graph, Vertex [] reverseGraph, int source, int target){ 154 | //create the PriorityQueue's 155 | int [] forwpriorityQ = new int[graph.length]; //for forward propagation 156 | int [] revpriorityQ = new int[graph.length]; //for reverse graph i.e backward propagation. 157 | 158 | //initialize the graph. 159 | initialize(graph,reverseGraph,forwpriorityQ,revpriorityQ,source,target); 160 | 161 | PriorityQueue queue = new PriorityQueue(); 162 | queue.makeQueue(graph, reverseGraph, forwpriorityQ, revpriorityQ, source,target); 163 | 164 | ArrayList forwprocessedVertices = new ArrayList(); //list to store the processed vertices in the forward propagation. 165 | ArrayList revprocessedVertices = new ArrayList(); //list to store the processed vertices in the reverse graph. i.e backward propagation. 166 | long correctDist = Long.MAX_VALUE; 167 | 168 | for(int i=0;i forwprocessedVertices, ArrayList revprocessedVertices, int vertex,long correctDist){ 212 | long distance = Long.MAX_VALUE; 213 | 214 | //process the list of forward processed vertices. 215 | for(int i=0;i graph[temp].distance + reverseGraph[temp].distance){ 218 | distance = graph[temp].distance + reverseGraph[temp].distance; 219 | } 220 | } 221 | 222 | //process the list of reverse processed vertices. 223 | for(int i=0;i graph[temp].distance + reverseGraph[temp].distance){ 226 | distance = graph[temp].distance + reverseGraph[temp].distance; 227 | } 228 | } 229 | 230 | return distance; 231 | } 232 | 233 | 234 | //main function to run the program. 235 | public static void main(String args[]) { 236 | Scanner in = new Scanner(System.in); 237 | System.out.println("Enter the number of vertices and edges."); 238 | int n = in.nextInt(); //number of vertices. 239 | int m = in.nextInt(); //number of edges. 240 | 241 | //create forward and reverse graph. 242 | Vertex [] graph = new Vertex[n]; 243 | Vertex [] reverseGraph = new Vertex[n]; 244 | 245 | //get the co-ordinates of the vertices. 246 | System.out.println("Enter the Coordinates."); 247 | for (int i = 0; i < n; i++) { 248 | int x, y; 249 | x = in.nextInt(); //x co-or 250 | y = in.nextInt(); //y co-or 251 | 252 | graph[i] = new Vertex(i,x,y); 253 | reverseGraph[i] = new Vertex(i,x,y); 254 | } 255 | 256 | 257 | //get the edges in the graph. 258 | System.out.println("Enter the edges with weights (V1 V2 W)."); 259 | for (int i = 0; i < m; i++) { 260 | int x, y, c; 261 | x = in.nextInt(); 262 | y = in.nextInt(); 263 | c = in.nextInt(); 264 | 265 | graph[x-1].adjList.add(y-1); 266 | graph[x-1].costList.add(c); 267 | 268 | reverseGraph[y-1].adjList.add(x-1); 269 | reverseGraph[y-1].costList.add(c); 270 | } 271 | 272 | System.out.println("Enter the number of queries."); 273 | int q = in.nextInt(); //number of queries 274 | 275 | System.out.println("Enter the queries (S T)"); 276 | for (int i = 0; i < q; i++) { 277 | int s, t; 278 | s = in.nextInt()-1; //source vertex. 279 | t = in.nextInt()-1; //target vertex. 280 | System.out.println(computeDist(graph,reverseGraph,s,t)); 281 | } 282 | } 283 | } -------------------------------------------------------------------------------- /Bidirectional Dijkstra/FriendSuggestion.java: -------------------------------------------------------------------------------- 1 | //Program to implement the Bi-Directional Dijkstra Algorithm. 2 | 3 | import java.util.Scanner; 4 | import java.util.ArrayList; 5 | import java.util.Arrays; 6 | import java.util.PriorityQueue; 7 | import java.util.Comparator; 8 | 9 | public class FriendSuggestion { 10 | 11 | //class Vertex of Graph. 12 | static class Vertex{ 13 | int vertexNum; //int vertexNum 14 | ArrayList adjList; //list of adjacent vertices. 15 | ArrayList costList; //list of cost or distance of adjacent vertices. 16 | 17 | int queuePos; //pos of vertex in the priorityqueue. 18 | long dist; //distance from start vetex. 19 | boolean processed; //is processed while traversing the graph. 20 | 21 | public Vertex(){ 22 | } 23 | 24 | 25 | //Vertex Constructor. 26 | public Vertex(int vertexNum){ 27 | this.vertexNum=vertexNum; 28 | this.adjList = new ArrayList(); 29 | this.costList = new ArrayList(); 30 | } 31 | 32 | 33 | //function to create the graph and reverse graph. forwPriorityQ for graph and revPriorityQ for reverse graph. 34 | public void createGraph(Vertex [] graph, Vertex [] reverseGraph, int [] forwPriorityQ, int [] revPriorityQ){ 35 | for(int i=0;i graph[priorityQ[2*index+1]].dist){ 84 | min = 2*index+1; 85 | } 86 | if(2*index+2 graph[priorityQ[2*index+2]].dist){ 87 | min = 2*index+2; 88 | } 89 | if(min!=index){ 90 | swap(graph,priorityQ,min,index); 91 | siftDown(min,graph,priorityQ,size); 92 | } 93 | } 94 | 95 | //function to change priority of an element.(priority can only be decreased.) 96 | public void changePriority(Vertex [] graph, int [] priorityQ, int index){ 97 | if((index-1)/2 > -1 && graph[priorityQ[index]].dist < graph[priorityQ[(index-1)/2]].dist){ 98 | swap(graph,priorityQ,index,(index-1)/2); 99 | changePriority(graph,priorityQ,(index-1)/2); 100 | } 101 | } 102 | } 103 | 104 | //function to relax edges i.e traverse only the adjacent vertices of the given vertex. 105 | private static void relaxEdges(Vertex [] graph, int vertex, int [] priorityQ, PriorityQueue queue,int queryId){ 106 | ArrayList vertexList = graph[vertex].adjList; //get the adjacent vertices list. 107 | ArrayList costList = graph[vertex].costList; //get the cost list of adjacent vertices. 108 | graph[vertex].processed = true; //mark processed true. 109 | 110 | for(int i=0;igraph[vertex].dist + cost){ 115 | graph[temp].dist = graph[vertex].dist + cost; 116 | queue.changePriority(graph,priorityQ,graph[temp].queuePos); 117 | } 118 | } 119 | } 120 | 121 | 122 | //function to compute distance between start vertex s and target vertex t. 123 | public static long computeDistance(Vertex [] graph, Vertex [] reverseGraph, int s, int t,int queryId){ 124 | 125 | //create two PriorityQueues forwQ for forward graph and revQ for reverse graph. 126 | PriorityQueue queue = new PriorityQueue(); 127 | int [] forwPriorityQ = new int[graph.length]; //for forward propagation. 128 | int [] revPriorityQ = new int[graph.length]; //for reverse propagation. 129 | 130 | //create graph. 131 | Vertex vertex = new Vertex(); 132 | vertex.createGraph(graph,reverseGraph,forwPriorityQ,revPriorityQ); 133 | 134 | //dist of s from s is 0. 135 | //in rev graph dist of t from t is 0. 136 | graph[s].dist=0; 137 | reverseGraph[t].dist=0; 138 | queue.makeQueue(graph,forwPriorityQ,s,t); 139 | queue.makeQueue(reverseGraph,revPriorityQ,t,s); 140 | 141 | //store the processed vertices while traversing. 142 | ArrayList forgraphprocessedVertices = new ArrayList(); //for forward propagation. 143 | ArrayList revgraphprocessedVertices = new ArrayList(); //for reverse propagation. 144 | 145 | 146 | for(int i=0;i forgraphprocessedVertices, ArrayList revgraphprocessedVertices,int queryId){ 192 | long distance = Integer.MAX_VALUE; 193 | 194 | //process the forward list. 195 | for(int i=0;i=Integer.MAX_VALUE){ 198 | continue; 199 | } 200 | long tempdist = graph[vertex].dist + reverseGraph[vertex].dist; 201 | if(distance>tempdist){ 202 | distance=tempdist; 203 | } 204 | } 205 | 206 | //process the reverse list. 207 | for(int i=0;i=Integer.MAX_VALUE){ 210 | continue; 211 | } 212 | long tempdist = reverseGraph[vertex].dist + graph[vertex].dist; 213 | if(distance>tempdist){ 214 | distance=tempdist; 215 | } 216 | 217 | } 218 | return distance; 219 | } 220 | 221 | 222 | //main function to run the program. 223 | public static void main(String args[]) { 224 | Scanner in = new Scanner(System.in); 225 | int n = in.nextInt(); //number of vertices. 226 | int m = in.nextInt(); //number of edges. 227 | 228 | //create two graphs forw graph and reverse graph. 229 | Vertex vertex = new Vertex(); 230 | Vertex [] graph = new Vertex[n]; 231 | Vertex [] reverseGraph = new Vertex[n]; 232 | 233 | //initialize the vertices. 234 | for(int i=0;i inEdges; //list of incoming edges to this vertex. 58 | ArrayList inECost; //list of incoming edges cost or distance. 59 | ArrayList outEdges; //list of outgoing edges from this vertex. 60 | ArrayList outECost; //list of out edges cost or distance. 61 | 62 | int orderPos; //position of vertex in nodeOrderingQueue. 63 | 64 | boolean contracted; //to check if vertex is contracted 65 | 66 | Distance distance; 67 | Processed processed; 68 | 69 | //parameters for computing importance according to which we will contract the vertices. Vertex wih least importance wil be contracted first. 70 | int edgeDiff; //egdediff = sE - inE - outE. (sE=inE*outE , i.e number of shortcuts that we may have to add.) 71 | long delNeighbors; //number of contracted neighbors. 72 | int shortcutCover; //number of shortcuts to be introduced if this vertex is contracted. 73 | 74 | long importance; //total importance = edgediff + shortcutcover + delneighbors. 75 | 76 | public Vertex(){ 77 | } 78 | 79 | public Vertex(int vertexNum){ 80 | this.vertexNum=vertexNum; 81 | this.inEdges = new ArrayList(); 82 | this.outEdges = new ArrayList(); 83 | this.inECost = new ArrayList(); 84 | this.outECost = new ArrayList(); 85 | this.distance = new Distance(); 86 | this.processed = new Processed(); 87 | this.delNeighbors = 0; 88 | this.contracted=false; 89 | } 90 | } 91 | 92 | 93 | //priorityQueue (based on min heap) dealing with importance parameter. 94 | public static class PQIMPcomparator implements Comparator{ 95 | public int compare(Vertex node1, Vertex node2){ 96 | if(node1.importance > node2.importance){ 97 | return 1; 98 | } 99 | if(node1.importance < node2.importance){ 100 | return -1; 101 | } 102 | return 0; 103 | } 104 | } 105 | 106 | 107 | //priorityQueue (min heap) dealing with distance while preprocessing time. 108 | static class PriorityQueueComp implements Comparator{ 109 | public int compare(Vertex node1,Vertex node2){ 110 | if(node1.distance.distance>node2.distance.distance){ 111 | return 1; 112 | } 113 | if(node1.distance.distance comp = new PQIMPcomparator(); 125 | PriorityQueue PQImp; //queue for importance parameter. 126 | 127 | Comparator PQcomp = new PriorityQueueComp(); 128 | PriorityQueue queue; //queue for distance parameter. 129 | 130 | 131 | //calculate initial importance for all vertices. 132 | private void computeImportance(Vertex [] graph){ 133 | PQImp = new PriorityQueue(graph.length,comp); 134 | for(int i=0;i PQImp.peek().importance){ 162 | PQImp.add(vertex); 163 | continue; 164 | } 165 | 166 | nodeOrdering[extractNum] = vertex.vertexNum; 167 | vertex.orderPos = extractNum; 168 | extractNum = extractNum + 1; 169 | 170 | //contraction part. 171 | contractNode(graph,vertex,extractNum-1); 172 | } 173 | return nodeOrdering; 174 | } 175 | 176 | 177 | //update the neighbors of the contracted vertex that this vertex is contracted. 178 | private void calNeighbors(Vertex [] graph,ArrayList inEdges, ArrayList outEdges){ 179 | for(int i=0;i inEdges = vertex.inEdges; 194 | ArrayList inECost = vertex.inECost; 195 | ArrayList outEdges = vertex.outEdges; 196 | ArrayList outECost = vertex.outECost; 197 | 198 | vertex.contracted=true; 199 | 200 | long inMax = 0; //stores the max distance out of uncontracted inVertices of the given vertex. 201 | long outMax =0; //stores the max distance out of uncontracted outVertices of the given vertex. 202 | 203 | calNeighbors(graph,vertex.inEdges,vertex.outEdges); //update the given vertex's neighbors about that the given vertex is contracted. 204 | 205 | for(int i=0; iincost+outcost){ 242 | graph[inVertex].outEdges.add(outVertex); 243 | graph[inVertex].outECost.add(incost+outcost); 244 | graph[outVertex].inEdges.add(inVertex); 245 | graph[outVertex].inECost.add(incost+outcost); 246 | } 247 | } 248 | } 249 | } 250 | 251 | 252 | //dijkstra function implemented. 253 | private void dijkstra(Vertex [] graph, int source, long maxcost, int contractId,int sourceId){ 254 | queue = new PriorityQueue(graph.length,PQcomp); 255 | 256 | graph[source].distance.distance = 0; 257 | graph[source].distance.contractId=contractId; 258 | graph[source].distance.sourceId = sourceId; 259 | 260 | queue.clear(); 261 | queue.add(graph[source]); 262 | 263 | int i=0; 264 | while(queue.size()!=0){ 265 | Vertex vertex = (Vertex)queue.poll(); 266 | if(i>3 || vertex.distance.distance > maxcost){ 267 | return; 268 | } 269 | relaxEdges(graph,vertex.vertexNum,contractId,queue,sourceId); 270 | } 271 | } 272 | 273 | //function to relax outgoing edges. 274 | private void relaxEdges(Vertex [] graph,int vertex,int contractId, PriorityQueue queue,int sourceId){ 275 | ArrayList vertexList = graph[vertex].outEdges; 276 | ArrayList costList = graph[vertex].outECost; 277 | 278 | for(int i=0;i graph[vertex].distance.distance + cost){ 285 | graph[temp].distance.distance = graph[vertex].distance.distance + cost; 286 | graph[temp].distance.contractId = contractId; 287 | graph[temp].distance.sourceId = sourceId; 288 | 289 | queue.remove(graph[temp]); 290 | queue.add(graph[temp]); 291 | } 292 | } 293 | } 294 | 295 | //compare the ids whether id of source to target is same if not then consider the target vertex distance=infinity. 296 | private boolean checkId(Vertex [] graph,int source,int target){ 297 | if(graph[source].distance.contractId != graph[target].distance.contractId || graph[source].distance.sourceId != graph[target].distance.sourceId){ 298 | return true; 299 | } 300 | return false; 301 | } 302 | 303 | //main function of this class. 304 | public int [] processing(Vertex [] graph){ 305 | computeImportance(graph); //find initial importance by traversing all vertices. 306 | int [] nodeOrdering = preProcess(graph); 307 | return nodeOrdering; 308 | } 309 | } 310 | 311 | 312 | 313 | 314 | //priorityQueue(min heap) for bidirectional dijkstra algorithms.(for forward search) 315 | public static class forwComparator implements Comparator{ 316 | public int compare(Vertex vertex1, Vertex vertex2){ 317 | if(vertex1.distance.queryDist>vertex2.distance.queryDist){ 318 | return 1; 319 | } 320 | if(vertex1.distance.queryDist{ 331 | public int compare(Vertex vertex1, Vertex vertex2){ 332 | if( vertex1.distance.revDistance>vertex2.distance.revDistance){ 333 | return 1; 334 | } 335 | if(vertex1.distance.revDistance forwComp = new forwComparator(); 347 | Comparator revComp = new revComparator(); 348 | PriorityQueue forwQ; 349 | PriorityQueue revQ; 350 | 351 | //main function that will compute distances. 352 | public long computeDist(Vertex [] graph, int source, int target, int queryID , int [] nodeOrdering){ 353 | graph[source].distance.queryDist = 0; 354 | graph[source].distance.forwqueryId = queryID; 355 | graph[source].processed.forwqueryId = queryID; 356 | 357 | graph[target].distance.revDistance = 0; 358 | graph[target].distance.revqueryId = queryID; 359 | graph[target].processed.revqueryId = queryID; 360 | 361 | forwQ = new PriorityQueue(graph.length,forwComp); 362 | revQ = new PriorityQueue(graph.length,revComp); 363 | 364 | forwQ.add(graph[source]); 365 | revQ.add(graph[target]); 366 | 367 | long estimate = Long.MAX_VALUE; 368 | 369 | while(forwQ.size()!=0 || revQ.size()!=0){ 370 | if(forwQ.size()!=0){ 371 | Vertex vertex1 = (Vertex)forwQ.poll(); 372 | if(vertex1.distance.queryDist<=estimate){ 373 | relaxEdges(graph,vertex1.vertexNum,"f",nodeOrdering,queryID); 374 | } 375 | if(vertex1.processed.revqueryId == queryID && vertex1.processed.revProcessed){ 376 | if(vertex1.distance.queryDist + vertex1.distance.revDistance < estimate){ 377 | estimate = vertex1.distance.queryDist + vertex1.distance.revDistance; 378 | } 379 | } 380 | } 381 | 382 | if(revQ.size()!=0){ 383 | Vertex vertex2 = (Vertex)revQ.poll(); 384 | if(vertex2.distance.revDistance <= estimate){ 385 | relaxEdges(graph,vertex2.vertexNum,"r",nodeOrdering,queryID); 386 | } 387 | if(vertex2.processed.forwqueryId == queryID && vertex2.processed.forwProcessed){ 388 | if(vertex2.distance.revDistance + vertex2.distance.queryDist < estimate){ 389 | estimate = vertex2.distance.queryDist + vertex2.distance.revDistance; 390 | } 391 | } 392 | } 393 | } 394 | 395 | if(estimate==Long.MAX_VALUE){ 396 | return -1; 397 | } 398 | return estimate; 399 | } 400 | 401 | 402 | 403 | //function to relax edges.(according to the direction forward or backward) 404 | private void relaxEdges(Vertex [] graph, int vertex,String str,int [] nodeOrdering, int queryId){ 405 | if(str == "f"){ 406 | ArrayList vertexList = graph[vertex].outEdges; 407 | ArrayList costList = graph[vertex].outECost; 408 | graph[vertex].processed.forwProcessed=true; 409 | graph[vertex].processed.forwqueryId = queryId; 410 | 411 | for(int i=0;i graph[vertex].distance.queryDist + cost){ 416 | graph[temp].distance.forwqueryId = graph[vertex].distance.forwqueryId; 417 | graph[temp].distance.queryDist = graph[vertex].distance.queryDist + cost; 418 | 419 | forwQ.remove(graph[temp]); 420 | forwQ.add(graph[temp]); 421 | } 422 | } 423 | } 424 | } 425 | else{ 426 | ArrayList vertexList = graph[vertex].inEdges; 427 | ArrayList costList = graph[vertex].inECost; 428 | graph[vertex].processed.revProcessed = true; 429 | graph[vertex].processed.revqueryId = queryId; 430 | 431 | for(int i=0;i graph[vertex].distance.revDistance + cost){ 437 | graph[temp].distance.revqueryId = graph[vertex].distance.revqueryId; 438 | graph[temp].distance.revDistance = graph[vertex].distance.revDistance + cost; 439 | 440 | revQ.remove(graph[temp]); 441 | revQ.add(graph[temp]); 442 | } 443 | } 444 | } 445 | } 446 | } 447 | 448 | } 449 | 450 | //main function to run the program. 451 | public static void main(String args[]) { 452 | Scanner in = new Scanner(System.in); 453 | int n = in.nextInt(); //number of vertices in the graph. 454 | int m = in.nextInt(); //number of edges in the graph. 455 | 456 | Vertex vertex = new Vertex(); 457 | Vertex [] graph = new Vertex[n]; 458 | 459 | //initialize the graph. 460 | for(int i=0;i