как найти кратчайший путь?

Всем привет! Помогите, пожалуйста решить задачу. Задача из яндекса. На 15-м тесте проваливается. Вот скрин задачи: введите сюда описание изображения введите сюда описание изображения

Вот пара примеров: введите сюда описание изображения

Вот мой код: Функция distance возвращает map в котором хранится пара вершин и вес ребра между ними. Дальше в функции main строится граф для поиска в ширину. В графе вершины считаются недостежимыми, если вес ребра больше k.

#include <iostream>
#include <vector>
#include <map>
#include <limits>
#include <queue>

const std::map<std::pair<int, int>, long long> distance(std::vector<std::pair<int, int>>& v)
{
    std::map<std::pair<int, int>, long long> my_map;
    
    int size = v.size();
    for(int i = 0; i < size; ++i)
    {
        for(int j = i + 1; j < size; ++j)
        {
            std::pair<int, int> p;
            p.first = i+1;
            p.second = j + 1;
            my_map[p] = abs(v[i].first - v[j].first) + abs(v[i].second - v[j].second);
        }
    }
    
    return my_map;
}

int bfs(std::vector<std::vector<int>>& graph, int k, int s, int e){
    const unsigned int INF = std::numeric_limits<int>::max();
    
    std::vector<int> dist(graph.size(), INF);
    std::queue<int> q;
    
    dist[s] = 0;
    q.push(s);
    
    while(!q.empty()){
        
        int v = q.front();
        q.pop();
        for(int to : graph[v]){
            if(dist[to] > dist[v] + 1){
                dist[to] = dist[v] + 1;
                q.push(to);
            }
        }
        
    }
    
    return dist[e] == INF ? -1 : dist[e];
}


int main()
{
    int amountCity;
    std::cin >> amountCity;

    std::vector<std::pair<int, int>> coordinats(amountCity);
    for(int i=0; i<amountCity; ++i)
    {
        std::cin>>coordinats[i].first>>coordinats[i].second;
    }
    
    int k, start, end;
    std::cin >> k >> start >> end;
    
    const std::map<std::pair<int, int>, long long> m = std::move(distance(coordinats));
    
    std::vector<std::vector<int>> v(amountCity);
    
    for(auto& [key, val]: m){
        if(val <= k){
            v[key.first-1].push_back(key.second-1);
            v[key.second-1].push_back(key.first-1);
        }
    }
    
    std::cout << bfs(v, k, start-1, end-1);
    


    return 0;
}

Ответы (1 шт):

Автор решения: Stanislav Volodarskiy

Попробуем тестировать. Тесты состоят из двух городов на расстоянии 40. Если задать k = 39 доехать нельзя. Если задать k = 40, доехать можно за одну поездку. Всё верно:

$ g++ -std=c++17 temp.cpp 

$ echo 2 -10 -10 10 10 39 1 2 | ./a.out 
-1
$ echo 2 -10 -10 10 10 40 1 2 | ./a.out 
1

В следующем тесте увеличим расстояние между городами до 4·109. Доехать оказывается можно:

$ echo 2 -1000000000 -1000000000 1000000000 1000000000 40 1 2 | ./a.out 
1

Потому что в строке my_map[p] = abs(v[i].first - v[j].first) + abs(v[i].second - v[j].second); переполнение. Отладочная печать показывает расстояние между городами -294967296.

То что my_map[p] имеет тип long long не имеет значения. Оператор + получает оба аргумента типа int и, по правилам языка, производит результат типа int. Сумма испорчена и после этого записана в результат.

→ Ссылка