I'm trying to implement the Bidirectional Dijkstra's algorithm with the Eucledean heuristics but when I submit it to the grader it crashes. At first time I was using a set to extract the minimum edge weight and I thought that was the error but I changed for a priority queue and nothing happened. I don't think it crashes because it uses a lot of memory, in the worst case it uses 880000 espaces in memory for the vectors, but maybe I don't know how estimate the amount of memory used in the worst case. Does anyone knows why my code could crash it?
Here is my code:
#include <cstdio>
#include <cassert>
#include <vector>
#include <limits>
#include <utility>
#include <math.h>
#include <queue>
#include <iostream>
using namespace std;
// Vector to represent a graph as an adjacency list
typedef vector<vector<vector<int>>> Adj;
// Distances can grow out of int type
typedef long long Len;
// Vector of two priority_queue - for forward and backward searches.
typedef vector<priority_queue<pair<Len, int>,vector<pair<Len,int>>,greater<pair<Len,int>>>> Queue;
const Len MAX_ = numeric_limits<Len>::max() / 4;
class AStar {
// Size of the nodes
int n_;
// adj_[0] and cost_[0] stores the original edges and its weights
// adj_[1] and cost_[1] stores the reverses edges and its weights
Adj adj_;
Adj cost_;
// distance_[0] stores the distance for the forward search
// distance_[1] stores the distance for the backward search
vector<vector<Len>> distance_;
// hdistance_[0] stores the distance plus the heuristics value for the forward search
// hdistance_[1] stores the distance plus the heuristics value for the backward search
vector<vector<Len>> hdistance_;
// Stores the nodes discovered in the path neither from source to target or from target to source
vector<int> workset_;
// Stores the visited nodes
vector<bool> visited_;
// Coordinates of the nodes
std::vector<std::pair<Len,Len>> xy_;
public:
AStar(int n, Adj adj, Adj cost, std::vector<std::pair<Len,Len>> xy)
: n_(n), adj_(adj), cost_(cost), distance_(2, vector<Len>(n_, MAX_)), hdistance_(2, vector<Len>(n_, MAX_)), visited_(n), xy_(xy),workset_(n)
{}
// Reset everything
void clear() {
for (unsigned int i = 0; i < workset_.size(); ++i) {
int v = workset_[i];
visited_[v] = false;
}
distance_= vector<vector<Len>>(2, vector<Len>(n_, MAX_));
hdistance_= vector<vector<Len>>(2, vector<Len>(n_, MAX_));
workset_.clear();
}
// Return the heuristic distance from the node to the target and from the source to the node
long long potential(int a, int side,int s, int t){
long long pi_f=sqrt(pow(xy_[a].first-xy_[t].first,2)+pow(xy_[a].second-xy_[t].second,2));
long long pi_r=sqrt(pow(xy_[s].first-xy_[a].first,2)+pow(xy_[s].second-xy_[a].second,2));
//cout<<"pi_f="<<pi_f<<", pi_r="<<pi_r<<'\n';
return side?(pi_r-pi_f)/2:(pi_f-pi_r)/2;
}
// Visit each neighbor node and change is distance value if it's needed
void visit(Queue& q, int side, pair<Len,int> u,int s, int t) {
for(unsigned int i=0; i<adj_[side][u.second].size();i++){
int v=adj_[side][u.second][i];
int w=cost_[side][u.second][i];
//cout<<"Node -> "<<v<<" ,distance: "<<w<<'\n';
long long h=potential(v,side,s,t);
//cout<<"heuristics: "<<h<<'\n';
//cout<<" - "<<distance_[side][v]<<" "<<distance_[side][u.second]+w<<'\n';
if((hdistance_[side][v]==MAX_)||(distance_[side][v]>distance_[side][u.second]+w)){
distance_[side][v]=distance_[side][u.second]+w;
hdistance_[side][v]=distance_[side][u.second]+w+h;
q[side].push(make_pair(hdistance_[side][v],v));
}
}
workset_.push_back(u.second);
}
// Returns the shortest distance to the target
Len Shortest_Path() {
long long distance=MAX_;
for(unsigned int i=0; i<workset_.size();i++){
if(distance_[0][workset_[i]]+distance_[1][workset_[i]]<distance){
distance=distance_[0][workset_[i]]+distance_[1][workset_[i]];
}
}
return distance;
}
// Process each query
Len query(int s, int t) {
clear();
Queue q(2);
q[0].push(make_pair(0,s));
q[1].push(make_pair(0,t));
distance_[0][s]=0;
hdistance_[0][s]=0;
hdistance_[1][t]=0;
distance_[1][t]=0;
pair<Len,int> v;
do{
// Forward search
if(q[0].size()==0){
break;
}
v=q[0].top();
q[0].pop();
//If it's a non-updated node
if(hdistance_[0][v.second]!=v.first){
continue;
}
visit(q,0,v,s,t);
if(visited_[v.second]==1){
return Shortest_Path();
}
visited_[v.second]=1;
// Backward search
if(q[1].size()==0){
break;
}
v=q[1].top();
q[1].pop();
//If it's a non-updated node
if(hdistance_[1][v.second]!=v.first){
continue;
}
visit(q,1,v,s,t);
if(visited_[v.second]==1){
return Shortest_Path();
}
visited_[v.second]=1;
}while(true);
return -1;
}
};
int main() {
int n, m;
scanf("%d%d", &n, &m);
std::vector<std::pair<Len,Len>> xy(n);
for (unsigned int i=0;i<n;++i){
int a, b;
scanf("%d%d", &a, &b);
xy[i] = make_pair(a,b);
}
Adj adj(2, vector<vector<int>>(n));
Adj cost(2, vector<vector<int>>(n));
for (unsigned int i=0; i<m; ++i) {
int u, v, c;
scanf("%d%d%d", &u, &v, &c);
adj[0][u-1].push_back(v-1);
cost[0][u-1].push_back(c);
adj[1][v-1].push_back(u-1);
cost[1][v-1].push_back(c);
}
AStar astar(n, adj, cost, xy);
int t;
scanf("%d", &t);
for (int i=0; i<t; ++i) {
int u, v;
scanf("%d%d", &u, &v);
printf("%lld\n", astar.query(u-1, v-1));
}
}
Here are the constraints:
Aucun commentaire:
Enregistrer un commentaire