Example #1
0
// 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;
}
Example #3
0
 inline void put(
     T item,
     Number priority)
 {
     elements.emplace(priority, item);
 }
 void push(T node, float priority) {
     elements.emplace(priority, node);
 }