This documentation is automatically generated by online-judge-tools/verification-helper
#include "../Utility/template.hpp"
#include "../Datastructure/range_edge_graph.hpp"
int main() {
int n = 10;
range_edge_graph gh(n); //n頂点で無辺のグラフを生成。
gh.add_edge(0, 3, 6, 9, 10, -1); // [0, 3) の頂点から [6, 9) に向けて 重み = 10の辺を追加。
gh.add_edge(6, 9, 9, 10, 5, -1); //[6, 9) の頂点から [9, 10) の頂点に向けて 重み = 5の辺を追加。
gh.add_edge(0, 9, 30, -1); // 0 から 9 に 重み = 30の辺を追加。
auto g = gh.graph();
int new_n = g.size();
//0から9への最短距離を求める。
vec<int> dist(new_n, 100000);
dist[0] = 0;
priority_queue<pair<int, int>, vector<pair<int, int>>, greater<pair<int, int>>> que;
que.emplace(0, 0);
while(!que.empty()) {
auto [c, v] = que.top();
que.pop();
if(dist[v] < c) continue;
for(auto e : g[v]) {
if(chmin(dist[e.to], e.cost + c)) {
que.emplace(dist[e.to], e.to);
}
}
}
cout << dist[9] << endl; //15
}
#line 1 "Utility/template.hpp"
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
#define rep(i, s, t) for (ll i = s; i < (ll)(t); i++)
#define rrep(i, s, t) for (ll i = (ll)(t) - 1; i >= (ll)(s); i--)
#define all(x) begin(x), end(x)
#define TT template <typename T>
TT using vec = vector<T>;
template <class T1, class T2> bool chmin(T1 &x, T2 y) {
return x > y ? (x = y, true) : false;
}
template <class T1, class T2> bool chmax(T1 &x, T2 y) {
return x < y ? (x = y, true) : false;
}
struct io_setup {
io_setup() {
ios::sync_with_stdio(false);
std::cin.tie(nullptr);
cout << fixed << setprecision(15);
}
} io_setup;
/*
@brief verify用テンプレート
*/
#line 1 "Datastructure/range_edge_graph.hpp"
struct range_edge_graph {
#define pb push_back
struct edge {
int to;
ll cost;
//ll cap; フローならこれも使う。
edge(){}
edge(int a, ll b, ll c) : to(a), cost(b) {}
//edge(int a, ll b, ll c) : to(a), cost(b), cap(c) {}
//フローの時のコンストラクタ
};
edge e(int to) {
return edge(to, 0, LLONG_MAX/4);
}
int n;
int sz = 1;
int node;
vec<vec<edge>> g;
range_edge_graph(int N) : n(N) {
while(sz < n) sz <<= 1;
g = vec<vec<edge>>(n + 4 * sz);
node = n + 4 * sz;
rep(i, 1, sz) {
g[i + n].pb( e(i * 2 + n) );
g[i + n].pb( e(i * 2 + 1 + n) );
g[i * 2 + n + 2 * sz].pb( e(i + n + 2 * sz) );
g[i * 2 + 1 + n + 2 * sz].pb( e(i + n + 2 * sz) );
}
rep(i, 0, n) {
g[i + n + sz].pb( e(i) );
g[i].pb( e(i + n + 3 * sz) );
}
}
void add_edge(int sl, int sr, int tl, int tr, ll cost, ll cap) {
int nw = node++;
int nw2 = node++;
g.pb({ edge( nw2, cost, cap ) });
g.pb(vec<edge>());
sl += sz;
sr += sz;
while(sl < sr) {
if(sl & 1) g[sl + n + 2 * sz].pb( e(nw) ), sl++;
if(sr & 1) sr--, g[sr + n + 2 * sz].pb( e(nw) );
sl >>= 1; sr >>= 1;
}
tl += sz;
tr += sz;
while(tl < tr) {
if(tl & 1) g[nw2].pb( e(tl + n) ), tl++;
if(tr & 1) tr--, g[nw2].pb( e(tr + n) );
tl >>= 1, tr >>= 1;
}
}
void add_edge(int s, int t, ll cost, ll cap) {
g[s].pb( edge(t, cost, cap) );
}
vec<vec<edge>> graph() {
return g;
}
#undef pb
};
/*
@brief 区間に辺を貼るテク
@docs doc/range_edge_graph.md
*/
#line 3 "example/range_edge_graph.example.cpp"
int main() {
int n = 10;
range_edge_graph gh(n); //n頂点で無辺のグラフを生成。
gh.add_edge(0, 3, 6, 9, 10, -1); // [0, 3) の頂点から [6, 9) に向けて 重み = 10の辺を追加。
gh.add_edge(6, 9, 9, 10, 5, -1); //[6, 9) の頂点から [9, 10) の頂点に向けて 重み = 5の辺を追加。
gh.add_edge(0, 9, 30, -1); // 0 から 9 に 重み = 30の辺を追加。
auto g = gh.graph();
int new_n = g.size();
//0から9への最短距離を求める。
vec<int> dist(new_n, 100000);
dist[0] = 0;
priority_queue<pair<int, int>, vector<pair<int, int>>, greater<pair<int, int>>> que;
que.emplace(0, 0);
while(!que.empty()) {
auto [c, v] = que.top();
que.pop();
if(dist[v] < c) continue;
for(auto e : g[v]) {
if(chmin(dist[e.to], e.cost + c)) {
que.emplace(dist[e.to], e.to);
}
}
}
cout << dist[9] << endl; //15
}