library

This documentation is automatically generated by online-judge-tools/verification-helper

View the Project on GitHub gyouzasushi/library

:heavy_check_mark: test/library-checker/shortest_path.test.cpp

Depends on

Code

#define PROBLEM "https://judge.yosupo.jp/problem/shortest_path"
#include <iostream>

#include "graph/dijkstra.hpp"
int main() {
    int n, m, s, t;
    std::cin >> n >> m >> s >> t;
    dijkstra<long long> d(n);
    for (int i = 0; i < m; i++) {
        int a, b;
        long long c;
        std::cin >> a >> b >> c;
        d.add_edge(a, b, c);
    }
    d.solve(s);
    if (!d.reachable(t)) {
        std::cout << -1 << '\n';
        return 0;
    }
    std::vector<int> path = d.path(t);
    std::cout << d.dist(t) << ' ' << path.size() - 1 << '\n';
    for (int i = 0; i + 1 < int(path.size()); i++) {
        std::cout << path[i] << ' ' << path[i + 1] << '\n';
    }
}
#line 1 "test/library-checker/shortest_path.test.cpp"
#define PROBLEM "https://judge.yosupo.jp/problem/shortest_path"
#include <iostream>

#line 2 "graph/dijkstra.hpp"
#include <algorithm>
#include <cassert>
#include <limits>
#include <queue>
#include <vector>
template <class T> struct dijkstra {
public:
    dijkstra() : dijkstra(0) {
    }
    explicit dijkstra(int n) : _n(n), g(n), _dist(n, inf), _prev(n, -1) {
    }
    void add_edge(int from, int to, T w) {
        assert(0 <= from && from < _n);
        assert(0 <= to && to < _n);
        g[from].emplace_back(to, w);
    }
    void solve(int s) {
        assert(0 <= s && s < _n);
        _dist.assign(_n, inf);
        _prev.assign(_n, -1);
        std::priority_queue<std::pair<T, int>, std::vector<std::pair<T, int>>,
                            std::greater<std::pair<T, int>>>
            que;
        _dist[s] = 0;
        que.emplace(0, s);
        while (!que.empty()) {
            auto [d, u] = que.top();
            que.pop();
            if (_dist[u] < d) continue;
            for (auto [v, w] : g[u]) {
                if (_dist[u] + w < _dist[v]) {
                    _dist[v] = _dist[u] + w;
                    _prev[v] = u;
                    que.emplace(_dist[v], v);
                }
            }
        }
    }
    T dist(int v) const {
        assert(0 <= v && v < _n);
        return _dist[v];
    }
    int prev(int v) const {
        assert(0 <= v && v < _n);
        return _prev[v];
    }
    bool reachable(int v) const {
        assert(0 <= v && v < _n);
        return _dist[v] != inf;
    }
    std::vector<int> path(int t) const {
        assert(0 <= t && t < _n);
        if (_dist[t] == inf) return {};
        std::vector<int> res;
        for (int v = t; v != -1; v = _prev[v]) res.push_back(v);
        std::reverse(res.begin(), res.end());
        return res;
    }

private:
    static constexpr T inf = std::numeric_limits<T>::max();
    int _n;
    std::vector<std::vector<std::pair<int, T>>> g;
    std::vector<T> _dist;
    std::vector<int> _prev;
};
#line 5 "test/library-checker/shortest_path.test.cpp"
int main() {
    int n, m, s, t;
    std::cin >> n >> m >> s >> t;
    dijkstra<long long> d(n);
    for (int i = 0; i < m; i++) {
        int a, b;
        long long c;
        std::cin >> a >> b >> c;
        d.add_edge(a, b, c);
    }
    d.solve(s);
    if (!d.reachable(t)) {
        std::cout << -1 << '\n';
        return 0;
    }
    std::vector<int> path = d.path(t);
    std::cout << d.dist(t) << ' ' << path.size() - 1 << '\n';
    for (int i = 0; i + 1 < int(path.size()); i++) {
        std::cout << path[i] << ' ' << path[i + 1] << '\n';
    }
}
Back to top page