std::unordered_map<int, std::vector<int>> graph;
std::vector<int> min_distance_to_city(n, std::numeric_limits<int>::max());
min_distance_to_city[0] = 0;
// create the normal connctions (directed edges).
for(int node = 0; node < (n - 1); node++) {
graph[node].push_back(node + 1);
min_distance_to_city[node] = node;
}
min_distance_to_city[n - 1] = n - 1;
// at each query
std::vector<int> shortest_distance_to_last_node;
// Define City{...}, city_comparator()
struct City{
int city;
int distance;
};
auto city_comparator = [](const City& city1, const City& city2) {
if (city1.distance == city2.distance) {
return city1.city < city2.city;
}
return city1.distance < city2.distance;
};
auto dijkstra = [&](int source) {
// imlementation using the set
// std::priority_queue<City, std::vector<City>, decltype(city_comparator)> cities_by_distance;
std::set<City, decltype(city_comparator)> cities_by_distance;
// cities_by_distance.push(
// City{
// .city = source,
// .distance = min_distance_to_city[source]
// }
// );
cities_by_distance.insert(
City{
.city = source,
.distance = min_distance_to_city[source]
}
);
std::unordered_set<int> visited_cities;
while(!cities_by_distance.empty()) {
// City current_city = cities_by_distance.top();
// int city_value = current_city.city;
// int city_distance = current_city.distance;
// cities_by_distance.pop();
City current_city = *cities_by_distance.begin();
cities_by_distance.erase(current_city);
// We probably do not need it in the case of a set.
// if (visited_cities.contains(city_value)) {
// continue;
// }
int city_value = current_city.city;
for(auto neighbor : graph[city_value]) {
if (min_distance_to_city[neighbor] > (min_distance_to_city[city_value] + 1)) {
// find and erase the city
// This is also O(logn)
cities_by_distance.erase(
City{
.city = neighbor,
.distance = min_distance_to_city[neighbor]
}
);
min_distance_to_city[neighbor] = (
min_distance_to_city[city_value] + 1
);
// cities_by_distance.push(
// City{
// .city = neighbor,
// .distance = min_distance_to_city[neighbor]
// }
// );
// insert this city into the queue
// I am assuming that this is O(logn)
cities_by_distance.insert(
City{
.city = neighbor,
.distance = min_distance_to_city[neighbor]
}
);
}
}
// visited_cities.insert(city_value);
}
};
for(auto query : queries) {
int source = query[0];
int destination = query[1];
// make the connection
graph[source].push_back(destination);
// run dijkstra
dijkstra(source);
shortest_distance_to_last_node.push_back(min_distance_to_city[n - 1]);
}
return shortest_distance_to_last_node;
}
};
But in terms of space complexity (where the claim is that set might save space), we did not gain much (deep sighs)