classSolution{publicintcountRestrictedPaths(intn,int[][]edges){List<List<Pair>>adj=newArrayList<>();for(inti=0;i<n;i++){adj.add(newArrayList<>());}for(intedge[]:edges){inti=edge[0]-1;intj=edge[1]-1;intw=edge[2];adj.get(i).add(newPair(j,w));adj.get(j).add(newPair(i,w));}intdistance[]=newint[n];Arrays.fill(distance,Integer.MAX_VALUE);Queue<Pair>q=newPriorityQueue<>((a,b)->Integer.compare(a.c,b.c));distance[n-1]=0;// dijsktras with last node as source, this way we will have shortest distance to reach to this node from all the other nodes ( because this will compute shortest distance from last node to all the other node hence vice versa is also true)q.add(newPair(n-1,0));while(!q.isEmpty()){Pairp=q.remove();intnode=p.j;intcost=p.c;if(cost>distance[node])continue;//additional optimization (code works without this though)for(PairadjPair:adj.get(node)){intadjNode=adjPair.j;intw=adjPair.c;if(distance[adjNode]>cost+w){distance[adjNode]=cost+w;q.add(newPair(adjNode,distance[adjNode]));}}}intdp[]=newint[n];Arrays.fill(dp,-1);intrestrictedPath=dfs(0,distance,adj,n-1,dp);returnrestrictedPath;}publicintdfs(inti,int[]distance,List<List<Pair>>adj,intlastNode,intdp[]){if(i==lastNode)return1;if(dp[i]!=-1)returndp[i];intcount=0;for(PairadjPair:adj.get(i)){intj=adjPair.j;if(distance[i]<=distance[j])continue;count+=dfs(j,distance,adj,lastNode,dp);count=(count)%((int)1e9+7);}returndp[i]=count;}}classPair{intj;intc;publicPair(intj,intc){this.j=j;this.c=c;}}