55import java .util .Comparator ;
66
77public class FriendSuggestion {
8-
9- static class Distance {
10- int queryId ;
11- int distance ;
12-
13- public Distance (){
14- this .queryId =-1 ;
15- this .distance = Integer .MAX_VALUE ;
16- }
17- }
18-
19- static class Processed {
20- int queryId ;
21- boolean processed ;
22-
23- public Processed (){
24- this .queryId =-1 ;
25- this .processed =false ;
26- }
27- }
28-
8+
299 static class Vertex {
3010int vertexNum ;
31- ArrayList <Integer > adjList ;
32- ArrayList <Integer > costList ;
33- //Distance distance;
34- //Processed processed;
11+ ArrayList <Integer > adjList ; //adjacent vertices of the vertex.
12+ ArrayList <Integer > costList ; //cost of adjacent edges of the vertex.
3513
36- int queuePos ;
37- long dist ;
38- boolean processed ;
14+ int queuePos ; //position of the vertex in the priorityQueue.
15+ long dist ; //distance is stored.
16+ boolean processed ; //is this vertex processed.
3917
4018public Vertex (){
4119}
@@ -44,10 +22,9 @@ public Vertex(int vertexNum){
4422this .vertexNum =vertexNum ;
4523this .adjList = new ArrayList <Integer >();
4624this .costList = new ArrayList <Integer >();
47- //this.distance = new Distance();
48- //this.processed = new Processed();
4925}
5026
27+ //initializes the instance variables.
5128public void createGraph (Vertex [] graph , Vertex [] reverseGraph , int [] forwPriorityQ , int [] revPriorityQ ){
5229for (int i =0 ;i <graph .length ;i ++){
5330graph [i ].queuePos =i ;
@@ -65,20 +42,11 @@ public void createGraph(Vertex [] graph, Vertex [] reverseGraph, int [] forwPrio
6542
6643 }
6744
68- /* static class QueueComp implements Comparator<Vertex>{
69- public int compare(Vertex vertex1, Vertex vertex2){
70- if(vertex1.distance.distance>vertex2.distance.distance){
71- return 1;
72- }
73-
74- if(vertex1.distance.distance<vertex2.distance.distance){
75- return -1;
76- }
77- return 0;
78- }
79- }*/
80-
45+
46+ //implemented the priorityQueue by myself.
8147 static class PriorityQueue {
48+
49+ //swap function maintaining the queuePos variable.
8250public void swap (Vertex [] graph , int [] priorityQ , int index1 , int index2 ){
8351int temp = priorityQ [index1 ];
8452
@@ -89,10 +57,13 @@ public void swap(Vertex [] graph, int [] priorityQ, int index1, int index2){
8957graph [temp ].queuePos =index2 ;
9058}
9159
60+ //makes the queue just put the source vertex at position zero ,target vertex has no role.
9261public void makeQueue (Vertex [] graph ,int [] forwpriorityQ , int source , int target ){
9362swap (graph , forwpriorityQ ,0 ,source );
9463}
9564
65+
66+ //extract the min elements i.e the first element.
9667public int extractMin (Vertex [] graph , int [] priorityQ , int extractNum ){
9768int vertex = priorityQ [0 ];
9869int size = priorityQ .length -1 -extractNum ;
@@ -101,6 +72,8 @@ public int extractMin(Vertex [] graph, int [] priorityQ, int extractNum){
10172return vertex ;
10273}
10374
75+
76+ //sift down the larger elements downwards.
10477public void siftDown (int index , Vertex [] graph , int [] priorityQ , int size ){
10578int min = index ;
10679if (2 *index +1 <size && graph [priorityQ [index ]].dist > graph [priorityQ [2 *index +1 ]].dist ){
@@ -115,140 +88,90 @@ public void siftDown(int index, Vertex [] graph, int [] priorityQ, int size){
11588}
11689}
11790
91+ //changes priority of the vertex.
11892public void changePriority (Vertex [] graph , int [] priorityQ , int index ){
11993if ((index -1 )/2 > -1 && graph [priorityQ [index ]].dist < graph [priorityQ [(index -1 )/2 ]].dist ){
12094swap (graph ,priorityQ ,index ,(index -1 )/2 );
12195changePriority (graph ,priorityQ ,(index -1 )/2 );
12296}
12397}
12498 }
125-
99+
100+
101+ //function to relax the edges of the vertex.
126102 private static void relaxEdges (Vertex [] graph , int vertex , int [] priorityQ , PriorityQueue queue ,int queryId ){
127103ArrayList <Integer > vertexList = graph [vertex ].adjList ;
128104ArrayList <Integer > costList = graph [vertex ].costList ;
129105graph [vertex ].processed = true ;
130- //graph[vertex].processed.queryId = queryId;
131-
132-
133106
134107for (int i =0 ;i <vertexList .size ();i ++){
135108int temp = vertexList .get (i );
136109int cost = costList .get (i );
137- /*if(graph[temp].distance.queryId != graph[vertex].distance.queryId || graph[temp].distance.distance>graph[vertex].distance.distance + cost){
138- graph[temp].distance.distance = graph[vertex].distance.distance + cost;
139- //graph[temp].distance.queryId = queryId ;
140- queue.changePriority(graph,priorityQ,graph[temp].queuePos);
141- //queue.remove(graph[temp]);
142- //queue.add(graph[temp]);
143- }*/
110+
144111if (graph [temp ].dist >graph [vertex ].dist + cost ){
145112graph [temp ].dist = graph [vertex ].dist + cost ;
146- //graph[temp].distance.queryId = queryId ;
147113queue .changePriority (graph ,priorityQ ,graph [temp ].queuePos );
148- //queue.remove(graph[temp]);
149- //queue.add(graph[temp]);
150114}
151115}
152116 }
153117
154- //static QueueComp comp = new QueueComp();
155- //static PriorityQueue<Vertex> forwQ = new PriorityQueue<Vertex>(comp);
156- //static PriorityQueue<Vertex> revQ = new PriorityQueue<Vertex>(comp);
157-
158- public static long computeDistance (Vertex [] graph , Vertex [] reverseGraph , int s , int t ,int queryId ){
159- //forwQ.clear();
160- //revQ.clear();
161-
162- //graph[s].distance.distance = 0;
163- //graph[s].distance.queryId = queryId;
164-
165- //reverseGraph[t].distance.distance = 0;
166- //reverseGraph[t].distance.queryId = queryId;
167-
168118
169- //forwQ.add(graph[s]);
170- //revQ.add(reverseGraph[t]);
119+ //bidirectional dijkstra implemented.
120+ public static long computeDistance (Vertex [] graph , Vertex [] reverseGraph , int s , int t ,int queryId ){
121+ PriorityQueue queue = new PriorityQueue (); //created priotityQueue object.
171122
172- PriorityQueue queue = new PriorityQueue ();
173- int [] forwPriorityQ = new int [graph .length ];
174- int [] revPriorityQ = new int [graph .length ];
123+ int [] forwPriorityQ = new int [graph .length ]; //priorityQ for forward search.
124+ int [] revPriorityQ = new int [graph .length ]; //priorityQ for backward search
175125
176126Vertex vertex = new Vertex ();
177- vertex .createGraph (graph ,reverseGraph ,forwPriorityQ ,revPriorityQ );
127+ vertex .createGraph (graph ,reverseGraph ,forwPriorityQ ,revPriorityQ ); //reinitializes the graph for each query.
178128
179- graph [s ].dist =0 ;
180- reverseGraph [t ].dist =0 ;
181- queue .makeQueue (graph ,forwPriorityQ ,s ,t );
182- queue .makeQueue (reverseGraph ,revPriorityQ ,t ,s );
183-
184-
185-
186- ArrayList <Integer > forgraphprocessedVertices = new ArrayList <Integer >();
187- ArrayList <Integer > revgraphprocessedVertices = new ArrayList <Integer >();
188-
129+ graph [s ].dist =0 ; //initialized source distance zero.
130+ reverseGraph [t ].dist =0 ; //initialized target distance to zero.
189131
132+ queue .makeQueue (graph ,forwPriorityQ ,s ,t ); //makes forwardQ.
133+ queue .makeQueue (reverseGraph ,revPriorityQ ,t ,s ); // makes revQ.
190134
135+ ArrayList <Integer > forgraphprocessedVertices = new ArrayList <Integer >(); //to store vertices processed in the forward search.
136+ ArrayList <Integer > revgraphprocessedVertices = new ArrayList <Integer >(); //to store vertices processed in the backward search.
137+
191138for (int i =0 ;i <graph .length ;i ++){
192- int vertex1 = queue .extractMin (graph ,forwPriorityQ ,i );
139+ int vertex1 = queue .extractMin (graph ,forwPriorityQ ,i ); //extracted the vertex with min distance.
193140if (graph [vertex1 ].dist ==Integer .MAX_VALUE ){
194141continue ;
195142}
196- relaxEdges (graph ,vertex1 ,forwPriorityQ ,queue ,queryId );
197- forgraphprocessedVertices .add (vertex1 );
143+ relaxEdges (graph ,vertex1 ,forwPriorityQ ,queue ,queryId ); //relaxed the edges.
144+ forgraphprocessedVertices .add (vertex1 ); //added in the forward lsit.
198145
146+ //check wether we have found vertex processed both in forward and backward then return the shortest path.
199147if (reverseGraph [vertex1 ].processed ){
200148return shortestPath (graph ,reverseGraph ,forgraphprocessedVertices ,revgraphprocessedVertices ,queryId );
201149}
202150
203151
204- int revVertex = queue .extractMin (reverseGraph ,revPriorityQ ,i );
152+ int revVertex = queue .extractMin (reverseGraph ,revPriorityQ ,i ); //extracted min distance vertex in backward search.
205153if (reverseGraph [revVertex ].dist ==Integer .MAX_VALUE ){
206154continue ;
207155}
208- relaxEdges (reverseGraph ,revVertex ,revPriorityQ ,queue ,queryId );
209- revgraphprocessedVertices .add (revVertex );
156+ relaxEdges (reverseGraph ,revVertex ,revPriorityQ ,queue ,queryId ); //relaxed edges in the backward search.
157+ revgraphprocessedVertices .add (revVertex ); //added the vertex to backward search processed list.
210158
159+ //check whether the vertex is processed in forward search as well then return shortest distance.
211160if (graph [revVertex ].processed ){
212161return shortestPath (graph ,reverseGraph ,forgraphprocessedVertices ,revgraphprocessedVertices ,queryId );
213162}
214-
215163}
216164
217- /*while(forwQ.size()!=0 || revQ.size()!=0){
218-
219- Vertex vertex = forwQ.poll();
220- if(vertex!=null){
221- relaxEdges(graph,vertex.vertexNum,forwQ,queryId);
222- forgraphprocessedVertices.add(vertex.vertexNum);
223-
224- if(reverseGraph[vertex.vertexNum].processed.queryId==queryId && reverseGraph[vertex.vertexNum].processed.processed){
225- return shortestPath(graph,reverseGraph,forgraphprocessedVertices,revgraphprocessedVertices,queryId);
226- }
227- }
228-
229- Vertex revVertex = revQ.poll();
230- if(revVertex!=null){
231- relaxEdges(reverseGraph,revVertex.vertexNum,revQ,queryId);
232- revgraphprocessedVertices.add(revVertex.vertexNum);
233-
234- if(graph[revVertex.vertexNum].processed.queryId==queryId && graph[revVertex.vertexNum].processed.processed){
235- return shortestPath(graph,reverseGraph,forgraphprocessedVertices,revgraphprocessedVertices,queryId);
236- }
237- }
238-
239- }*/
240165return -1 ;
241166 }
242167
243168
169+ //function to calculate shortest distance.
244170 private static long shortestPath (Vertex [] graph , Vertex [] reverseGraph , ArrayList <Integer > forgraphprocessedVertices , ArrayList <Integer > revgraphprocessedVertices ,int queryId ){
245171long distance = Integer .MAX_VALUE ;
246172
247173for (int i =0 ;i <forgraphprocessedVertices .size ();i ++){
248174int vertex = forgraphprocessedVertices .get (i );
249- /*if(reverseGraph[vertex].distance.queryId!=queryId || reverseGraph[vertex].distance.distance + graph[vertex].distance.distance>=Integer.MAX_VALUE){
250- continue;
251- }*/
252175if (reverseGraph [vertex ].dist + graph [vertex ].dist >=Integer .MAX_VALUE ){
253176continue ;
254177}
@@ -260,9 +183,6 @@ private static long shortestPath(Vertex [] graph, Vertex [] reverseGraph, ArrayL
260183
261184for (int i =0 ;i <revgraphprocessedVertices .size ();i ++){
262185int vertex = revgraphprocessedVertices .get (i );
263- /*if(graph[vertex].distance.queryId!=queryId || reverseGraph[vertex].distance.distance + graph[vertex].distance.distance>=Integer.MAX_VALUE){
264- continue;
265- }*/
266186if (reverseGraph [vertex ].dist + graph [vertex ].dist >=Integer .MAX_VALUE ){
267187continue ;
268188}
@@ -276,14 +196,16 @@ private static long shortestPath(Vertex [] graph, Vertex [] reverseGraph, ArrayL
276196 }
277197
278198
199+
200+ //main function to drive the program.
279201 public static void main (String args []) {
280202Scanner in = new Scanner (System .in );
281- int n = in .nextInt ();
282- int m = in .nextInt ();
203+ int n = in .nextInt (); //number of vertices.
204+ int m = in .nextInt (); //number of edges.
283205
284- Vertex vertex = new Vertex ();
285- Vertex [] graph = new Vertex [n ];
286- Vertex [] reverseGraph = new Vertex [n ];
206+ Vertex vertex = new Vertex ();
207+ Vertex [] graph = new Vertex [n ]; //graph for forward search.
208+ Vertex [] reverseGraph = new Vertex [n ]; //graph for backward search.
287209
288210for (int i =0 ;i <n ;i ++){
289211graph [i ]=new Vertex (i );
@@ -294,7 +216,7 @@ public static void main(String args[]) {
294216int u , v ;
295217int w ;
296218u = in .nextInt ();
297- v =in .nextInt ();
219+ v =in .nextInt ();
298220w =in .nextInt ();
299221
300222graph [u -1 ].adjList .add (v -1 );
@@ -304,7 +226,7 @@ public static void main(String args[]) {
304226reverseGraph [v -1 ].costList .add (w );
305227}
306228
307- int q = in .nextInt ();
229+ int q = in .nextInt (); //number of queries.
308230
309231 for (int i = 0 ; i < q ; i ++) {
310232 int s , t ;
0 commit comments