// Helper function for find_path_between_intersections. Iterates through the // outward edges of the given node. Calculates the heuristic and cost of every // outward node, then adds them to the wavefront. If an outward node has not // been added to nodeMap, it is added. void handle_node_edges(const LatLon& endPosition, Node& node , std::unordered_map<unsigned, Node>& nodeMap , std::priority_queue<waveElem, std::vector<waveElem>, std::greater<waveElem>>& wavefront) { std::vector<unsigned> segmentIDs = find_intersection_street_segments(node.id); unsigned id; for (const unsigned& segmentID : segmentIDs) { StreetSegmentEnds ends = getStreetSegmentEnds(segmentID); if (ends.from == node.id) id = ends.to; else if (!getStreetSegmentOneWay(segmentID)) id = ends.from; else continue; if (id == node.fromNodeID || id == node.id) continue; double cost = node.cost + find_segment_travel_time(segmentID); if (node.reachingEdge != ULONG_MAX && getStreetSegmentStreetID(node.reachingEdge) != getStreetSegmentStreetID(segmentID)) cost += 0.25; LatLon position = getIntersectionPosition(id); if (nodeMap.find(id) == nodeMap.end()) { nodeMap.insert(std::make_pair(id, Node(id, segmentID, node.id, ULONG_MAX))); // calculate the heuristic using the ideal case of // traversing the remaining distance directly to the // destination at 100 km/h double heuristic; heuristic = find_distance_between_two_points(endPosition , position); heuristic = heuristic/1000.0/100.0*60.0; wavefront.emplace(id, segmentID, node.id, cost, heuristic); } else if (cost < nodeMap.find(id)->second.cost) { double heuristic; heuristic = find_distance_between_two_points(endPosition , position); heuristic = heuristic/1000.0/100.0*60.0; wavefront.emplace(id, segmentID, node.id, cost, heuristic); } } }
int main() { std::ios_base::sync_with_stdio(false); cin >> N >> M; int low = 999999; for (int i = 1; i <= N; i++) { for (int j = 1; j <= M; j++) { char t = ' '; cin >> t; arr[j][i] = t; dist[j][i][0] = 99999; dist[j][i][1] = 99999; dist[j][i][2] = 99999; dist[j][i][3] = 99999; scanned[j][i][0] = false; scanned[j][i][1] = false; scanned[j][i][2] = false; scanned[j][i][3] = false; } } dist[1][1][2] = 0; bfsQ.emplace(bfs_data(1, 1, '>', 0)); while (!bfsQ.empty()) { int x = bfsQ.top().x; int y = bfsQ.top().y; //curent vertex char dir = bfsQ.top().dir; bfsQ.pop(); if (!(x > M || x<1 || y>N || y < 1) && arr[x][y] != '#') { int n_x = x, n_y = y; int t=-1; //direction indicator if (dir == '^') { n_y--; t = 0; } else if (dir == 'v') { n_y++; t = 1; } else if (dir == '>') { n_x++; t = 2; } else if (dir == '<') { n_x--; t = 3; } if (!scanned[x][y][t]) { if (x == M) { if(dist[x][y][t] < low) low = dist[x][y][t]; break; } scanned[x][y][t] = true; if (arr[n_x][n_y] != '#') { if (!scanned[n_x][n_y][t]) { if (dist[x][y][t] < dist[n_x][n_y][t]) { dist[n_x][n_y][t] = dist[x][y][t]; bfsQ.push(bfs_data(n_x, n_y, dir, dist[x][y][t])); } } } else { n_y = y; n_x = x; int n_t = -1; char ndir = '>'; if (dir == '^') { n_x --; n_t = 3; ndir= '<'; } else if (dir == 'v') { n_x--; n_t = 3; ndir= '<'; } else if (dir == '>') { n_y--; n_t = 0; ndir= '^'; } else if (dir == '<') { n_y--; n_t = 0; ndir= '^'; } if (!scanned[n_x][n_y][n_t]) { if (dist[x][y][t] < dist[n_x][n_y][n_t] + 1) { dist[n_x][n_y][n_t] = dist[x][y][t]+1; bfsQ.push(bfs_data(n_x, n_y, ndir, dist[x][y][t] + 1)); } } n_y = y; n_x = x; n_t = -1; if (dir == '^') { n_x ++; n_t = 2; ndir= '>'; } else if (dir == 'v') { n_x++; n_t = 2; ndir= '>'; } else if (dir == '>') { n_y++; n_t = 1; ndir= 'v'; } else if (dir == '<') { n_y++; n_t = 1; ndir= 'v'; } if (!scanned[n_x][n_y][n_t]) { if (dist[x][y][t] < dist[n_x][n_y][n_t] + 1) { dist[n_x][n_y][n_t] = dist[x][y][t]+1; bfsQ.push(bfs_data(n_x, n_y, ndir, dist[x][y][t] + 1)); } } } } } } cout << low; return 0; }
inline void put( T item, Number priority) { elements.emplace(priority, item); }
void push(T node, float priority) { elements.emplace(priority, node); }