This documentation is automatically generated by online-judge-tools/verification-helper
#include "cplib/graph/dijkstra.hpp"
#ifndef CPLIB_DIJKSTRA_HPP
#define CPLIB_DIJKSTRA_HPP
#include "cplib/graph/graph.hpp"
#include <algorithm>
#include <cmath>
#include <limits>
#include <set>
#include <utility>
#include <vector>
namespace cplib
{
using namespace std;
template <typename W, W INF = numeric_limits<W>::max()>
struct Dijkstra
{
Graph<W> const &g;
int src;
vector<int> p;
vector<W> d;
Dijkstra(Graph<W> const &g) : g(g), p(g.size()), d(g.size()){};
void run(int src = 0)
{
this->src = src;
fill(begin(p), end(p), -1);
fill(begin(d), end(d), INF);
set<pair<W, int>> q;
d[src] = 0;
q.emplace(d[src], src);
while (!q.empty())
{
int u = q.begin()->second;
q.erase(q.begin());
for (auto [v, w] : g[u])
{
if (d[u] + w < d[v])
{
q.erase({d[v], v});
d[v] = d[u] + w;
p[v] = u;
q.emplace(d[v], v);
}
}
}
}
void run_avoid(int src, int prohibited)
{
this->src = src;
fill(begin(p), end(p), -1);
fill(begin(d), end(d), INF);
set<pair<W, int>> q;
d[src] = 0;
q.emplace(d[src], src);
while (!q.empty())
{
int u = q.begin()->second;
q.erase(q.begin());
for (auto [v, w] : g[u])
{
if (v == prohibited)
continue;
if (d[u] + w < d[v])
{
q.erase({d[v], v});
d[v] = d[u] + w;
p[v] = u;
q.emplace(d[v], v);
}
}
}
}
Graph<W> shortest_path_DAG(void) const
{
int n = g.size();
Graph<W> dag(n);
for (int v = 0; v < n; ++v)
if (auto u = p[v]; u != -1)
dag.add_edge(u, v, d[v] - d[u]);
return dag;
}
vector<int> shortest_path(int u) const
{
if (d[u] == INF)
return {};
vector<int> path;
for (int v = u; v != src; v = p[v])
path.push_back(v);
path.push_back(src);
reverse(begin(path), end(path));
return path;
}
bool is_reachable(int u) { return d[u] != INF; }
W distance(int u) { return d[u]; }
void operator()(int src = 0) { run(src); }
};
} // namespace cplib
#endif // CPLIB_DIJKSTRA_HPP
#line 1 "cplib/graph/dijkstra.hpp"
#line 1 "cplib/graph/graph.hpp"
#include <algorithm>
#include <cassert>
#include <utility>
#include <vector>
namespace cplib
{
using namespace std;
template <typename W>
struct Graph
{
using adj_list = vector<pair<int, W>>;
vector<adj_list> g;
Graph(int n = 0) : g(n) {}
size_t size() const { return g.size(); }
int vertex(pair<int, W> e) const { return e.first; }
void add_edge(int u, int v) { g[u].emplace_back(v, W()); }
void add_edge(int u, int v, W weights) { g[u].emplace_back(v, weights); }
void add_undirected_edge(int u, int v)
{
g[u].emplace_back(v, W());
g[v].emplace_back(u, W());
}
void add_undirected_edge(int u, int v, W weights)
{
g[u].emplace_back(v, weights);
g[v].emplace_back(u, weights);
}
int add_node(void)
{
g.push_back({});
return g.size() - 1;
}
adj_list &operator[](int u) { return g[u]; }
adj_list operator[](int u) const { return g[u]; }
typename vector<adj_list>::iterator begin() { return g.begin(); };
typename vector<adj_list>::iterator end() { return g.end(); }
typename vector<adj_list>::const_iterator begin() const
{
return g.begin();
};
typename vector<adj_list>::const_iterator end() const { return g.end(); }
};
template <>
struct Graph<void>
{
using adj_list = vector<int>;
vector<adj_list> g;
Graph(int n = 0) : g(n) {}
size_t size() const { return g.size(); }
int vertex(int e) const { return e; }
void add_edge(int u, int v) { g[u].emplace_back(v); }
void add_undirected_edge(int u, int v)
{
g[u].push_back(v);
g[v].push_back(u);
}
int add_node(void)
{
g.push_back({});
return g.size() - 1;
}
adj_list &operator[](int u) { return g[u]; }
adj_list operator[](int u) const { return g[u]; }
typename vector<adj_list>::iterator begin() { return g.begin(); };
typename vector<adj_list>::iterator end() { return g.end(); }
typename vector<adj_list>::const_iterator begin() const
{
return g.begin();
};
typename vector<adj_list>::const_iterator end() const { return g.end(); }
};
using UndirectedGraph = Graph<void>;
} // namespace cplib
#line 6 "cplib/graph/dijkstra.hpp"
#include <cmath>
#include <limits>
#include <set>
#line 11 "cplib/graph/dijkstra.hpp"
namespace cplib
{
using namespace std;
template <typename W, W INF = numeric_limits<W>::max()>
struct Dijkstra
{
Graph<W> const &g;
int src;
vector<int> p;
vector<W> d;
Dijkstra(Graph<W> const &g) : g(g), p(g.size()), d(g.size()){};
void run(int src = 0)
{
this->src = src;
fill(begin(p), end(p), -1);
fill(begin(d), end(d), INF);
set<pair<W, int>> q;
d[src] = 0;
q.emplace(d[src], src);
while (!q.empty())
{
int u = q.begin()->second;
q.erase(q.begin());
for (auto [v, w] : g[u])
{
if (d[u] + w < d[v])
{
q.erase({d[v], v});
d[v] = d[u] + w;
p[v] = u;
q.emplace(d[v], v);
}
}
}
}
void run_avoid(int src, int prohibited)
{
this->src = src;
fill(begin(p), end(p), -1);
fill(begin(d), end(d), INF);
set<pair<W, int>> q;
d[src] = 0;
q.emplace(d[src], src);
while (!q.empty())
{
int u = q.begin()->second;
q.erase(q.begin());
for (auto [v, w] : g[u])
{
if (v == prohibited)
continue;
if (d[u] + w < d[v])
{
q.erase({d[v], v});
d[v] = d[u] + w;
p[v] = u;
q.emplace(d[v], v);
}
}
}
}
Graph<W> shortest_path_DAG(void) const
{
int n = g.size();
Graph<W> dag(n);
for (int v = 0; v < n; ++v)
if (auto u = p[v]; u != -1)
dag.add_edge(u, v, d[v] - d[u]);
return dag;
}
vector<int> shortest_path(int u) const
{
if (d[u] == INF)
return {};
vector<int> path;
for (int v = u; v != src; v = p[v])
path.push_back(v);
path.push_back(src);
reverse(begin(path), end(path));
return path;
}
bool is_reachable(int u) { return d[u] != INF; }
W distance(int u) { return d[u]; }
void operator()(int src = 0) { run(src); }
};
} // namespace cplib