This documentation is automatically generated by competitive-verifier/competitive-verifier
 Shortest Path (verify/graph/shortest_path.test.cpp)
 Shortest Path (verify/graph/shortest_path.test.cpp)
 cp-algo/graph/base.hpp
 cp-algo/graph/base.hpp cp-algo/graph/edge_types.hpp
 cp-algo/graph/edge_types.hpp cp-algo/graph/shortest_path.hpp
 cp-algo/graph/shortest_path.hpp cp-algo/structures/stack_union.hpp
 cp-algo/structures/stack_union.hpp// @brief Shortest Path
#define PROBLEM "https://judge.yosupo.jp/problem/shortest_path"
#pragma GCC optimize("Ofast,unroll-loops")
#include "cp-algo/graph/shortest_path.hpp"
#include <bits/stdc++.h>
using namespace std;
using namespace cp_algo::graph;
void solve() {
    int n, m, s, t;
    cin >> n >> m >> s >> t;
    graph<directed, weighted_edge> g(n);
    g.read_edges(m);
    auto [X, Y] = shortest_path(g, s, t);
    if(X == -1) {
        cout << X << "\n";
    } else {
        cout << X << ' ' << size(Y) << "\n";
        for(auto [u, e]: Y) {
            cout << u << ' ' << g.edge(e).to << "\n";
        }
    }
}
signed main() {
    //freopen("input.txt", "r", stdin);
    ios::sync_with_stdio(0);
    cin.tie(0);
    int t = 1;
    //cin >> t;
    while(t--) {
        solve();
    }
}
#line 1 "verify/graph/shortest_path.test.cpp"
// @brief Shortest Path
#define PROBLEM "https://judge.yosupo.jp/problem/shortest_path"
#pragma GCC optimize("Ofast,unroll-loops")
#line 1 "cp-algo/graph/shortest_path.hpp"
#line 1 "cp-algo/graph/base.hpp"
#line 1 "cp-algo/graph/edge_types.hpp"
#include <iostream>
#include <cstdint>
namespace cp_algo::graph {
    using node_index = int;
    struct edge_base {
        node_index to;
        edge_base() {}
        edge_base(node_index v): to(v) {}
        static auto read(node_index v0 = 0) {
            node_index u, v;
            std::cin >> u >> v;
            return std::pair{u - v0, edge_base(v - v0)};
        }
        edge_base backedge(int from) const {
            return {from};
        }
    };
    struct weighted_edge: edge_base {
        int64_t w;
        weighted_edge() {}
        weighted_edge(node_index v, int64_t w): edge_base(v), w(w) {}
        static auto read(node_index v0 = 0) {
            node_index u, v;
            int64_t w;
            std::cin >> u >> v >> w;
            return std::pair{u - v0, weighted_edge{v - v0, w}};
        }
        weighted_edge backedge(node_index from) const {
            return {from, w};
        }
    };
    template<typename edge>
    concept edge_type = std::is_base_of_v<edge_base, edge>;
    template<typename edge>
    concept weighted_edge_type = std::is_base_of_v<weighted_edge, edge>;
}
#line 1 "cp-algo/structures/stack_union.hpp"
#include <cstddef>
#include <vector>
namespace cp_algo::structures {
    template<class datatype>
    struct stack_union {
        stack_union(int n = 0): head(n), next(1), data(1) {}
        void push(int v, datatype const& vdata) {
            next.push_back(head[v]);
            head[v] = (int)std::size(next) - 1;
            data.push_back(vdata);
        }
        template<typename... Args>
        void emplace(int v, Args&&... vdata) {
            next.push_back(head[v]);
            head[v] = size(next) - 1;
            data.emplace_back(std::forward<Args...>(vdata...));
        }
        void reserve(int m) {
            data.reserve(m);
            next.reserve(m);
        }
        size_t size() const {return std::size(head);}
        size_t nodes() const {return std::size(data);}
        std::vector<int> head, next;
        std::vector<datatype> data;
    };
}
#line 5 "cp-algo/graph/base.hpp"
#include <ranges>
#line 7 "cp-algo/graph/base.hpp"
namespace cp_algo::graph {
    using edge_index = int;
    enum type {directed = 0, undirected = 1};
    template<type _undirected, edge_type edge_t = edge_base>
    struct graph {
        static constexpr bool undirected = _undirected;
        graph(int n, int v0 = 0): v0(v0), adj(n) {}
        void add_edge(node_index u, edge_t e) {
            adj.push(u, (edge_index)size(edges));
            edges.push_back(e);
            if constexpr (undirected) {
                adj.push(e.to, (edge_index)size(edges));
            }
            edges.push_back(e.backedge(u));
        }
        void read_edges(node_index m) {
            adj.reserve(m);
            for(edge_index i = 0; i < m; i++) {
                auto [u, e] = edge_t::read(v0);
                add_edge(u, e);
            }
        }
        void call_adjacent(node_index v, auto &&callback, auto &&terminate) const {
            for(int sv = adj.head[v]; sv && !terminate(); sv = adj.next[sv]) {
                callback(adj.data[sv]);
            }
        }
        void call_adjacent(node_index v, auto &&callback) const {
            call_adjacent(v, callback, [](){return false;});
        }
        void call_edges(auto &&callback) const {
            for(edge_index e: edges_view()) {
                callback(e);
            }
        }
        auto nodes_view() const {
            return std::views::iota(0, n());
        }
        auto edges_view() const {
            return std::views::iota(0, 2 * m()) | std::views::stride(2);
        }
        auto const& incidence_lists() const {return adj;}
        edge_t const& edge(edge_index e) const {return edges[e];}
        node_index n() const {return (node_index)adj.size();}
        edge_index m() const {return (edge_index)size(edges) / 2;}
    private:
        node_index v0;
        std::vector<edge_t> edges;
        structures::stack_union<edge_index> adj;
    };
}
#line 4 "cp-algo/graph/shortest_path.hpp"
#include <algorithm>
#include <queue>
namespace cp_algo::graph {
    template<type _, weighted_edge_type edge_t>
    auto dijkstra(graph<_, edge_t> const& g, int s) {
        static constexpr uint64_t inf = 1e18;
        std::vector<uint64_t> dist(g.n(), inf);
        std::vector<std::pair<node_index, edge_index>> pre(g.n());
        using que_t = std::pair<uint64_t, node_index>;
        std::priority_queue<que_t, std::vector<que_t>, std::greater<>> que;
        dist[s] = 0;
        que.push({0, s});
        while(!empty(que)) {
            auto [dv, v] = que.top();
            que.pop();
            if(dv != dist[v]) {
                continue;
            }
            g.call_adjacent(v, [&](auto e) {
                node_index u = g.edge(e).to;
                auto w = g.edge(e).w;
                if(dist[v] + w < dist[u]) {
                    pre[u] = {v, e};
                    dist[u] = dist[v] + w;
                    que.push({dist[u], u});
                }
            });
        }
        return std::pair{dist, pre};
    }
    template<type _, weighted_edge_type edge_t>
    auto shortest_path(graph<_, edge_t> const& g, int s, int t) {
        static constexpr uint64_t inf = 1e18;
        auto [dist, pre] = dijkstra(g, s);
        std::vector<std::pair<node_index, edge_index>> path;
        int64_t d = dist[t] == inf ? -1 : dist[t];
        while(d != -1 && t != s) {
            path.push_back(pre[t]);
            t = pre[t].first;
        }
        std::ranges::reverse(path);
        return std::pair{d, path};
    }
}
#line 5 "verify/graph/shortest_path.test.cpp"
#include <bits/stdc++.h>
using namespace std;
using namespace cp_algo::graph;
void solve() {
    int n, m, s, t;
    cin >> n >> m >> s >> t;
    graph<directed, weighted_edge> g(n);
    g.read_edges(m);
    auto [X, Y] = shortest_path(g, s, t);
    if(X == -1) {
        cout << X << "\n";
    } else {
        cout << X << ' ' << size(Y) << "\n";
        for(auto [u, e]: Y) {
            cout << u << ' ' << g.edge(e).to << "\n";
        }
    }
}
signed main() {
    //freopen("input.txt", "r", stdin);
    ios::sync_with_stdio(0);
    cin.tie(0);
    int t = 1;
    //cin >> t;
    while(t--) {
        solve();
    }
}
| Env | Name | Status | Elapsed | Memory | 
|---|---|---|---|---|
| g++ | almost_line_00 |  AC | 162 ms | 35 MB | 
| g++ | almost_line_01 |  AC | 160 ms | 33 MB | 
| g++ | almost_line_02 |  AC | 154 ms | 37 MB | 
| g++ | example_00 |  AC | 5 ms | 4 MB | 
| g++ | example_01 |  AC | 4 ms | 4 MB | 
| g++ | grid_random_00 |  AC | 131 ms | 28 MB | 
| g++ | grid_swirl_00 |  AC | 177 ms | 33 MB | 
| g++ | line_00 |  AC | 261 ms | 46 MB | 
| g++ | max_dense_long_00 |  AC | 89 ms | 28 MB | 
| g++ | max_dense_random_00 |  AC | 89 ms | 28 MB | 
| g++ | max_dense_random_01 |  AC | 87 ms | 25 MB | 
| g++ | max_dense_zero_00 |  AC | 80 ms | 28 MB | 
| g++ | max_sparse_random_00 |  AC | 103 ms | 35 MB | 
| g++ | max_sparse_random_01 |  AC | 155 ms | 34 MB | 
| g++ | max_sparse_random_02 |  AC | 160 ms | 35 MB | 
| g++ | max_star_00 |  AC | 175 ms | 51 MB | 
| g++ | max_star_01 |  AC | 218 ms | 46 MB | 
| g++ | small_00 |  AC | 5 ms | 4 MB | 
| g++ | small_01 |  AC | 5 ms | 4 MB | 
| g++ | small_02 |  AC | 4 ms | 4 MB | 
| g++ | small_03 |  AC | 4 ms | 4 MB | 
| g++ | small_04 |  AC | 4 ms | 4 MB | 
| g++ | sparse_random_00 |  AC | 87 ms | 34 MB | 
| g++ | sparse_random_01 |  AC | 88 ms | 38 MB | 
| g++ | sparse_random_02 |  AC | 98 ms | 23 MB | 
| g++ | spfa_killer_00 |  AC | 214 ms | 42 MB | 
| g++ | wrong_dijkstra_handmade_00 |  AC | 5 ms | 4 MB | 
| g++ | wrong_dijkstra_killer_00 |  AC | 161 ms | 39 MB | 
| g++ | wrong_dijkstra_killer_01 |  AC | 253 ms | 41 MB |