This documentation is automatically generated by competitive-verifier/competitive-verifier
// competitive-verifier: PROBLEM https://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=GRL_1_C
#include "graph/bellman_ford.hpp"
#include "graph/ford_fulkerson.hpp"
#include "graph/scc.hpp"
#include "prelude.hpp"
int n, m;
vector<pair<int, ll>> G[100];
int main() {
scanf("%d%d", &n, &m);
rep(_, m) {
int u, v;
int w;
scanf("%d%d%d", &u, &v, &w);
G[u].emplace_back(v, w);
}
scc scc(G);
for (auto& vs : scc.groups())
if (bellman_ford(G, vs[0]).first) return printf("NEGATIVE CYCLE\n"), 0;
auto d = ford_fulkerson(G);
rep(v, n) rep(i, n) printf(
"%s%c", d[v][i] == LONG_LONG_MAX ? "INF" : to_string(d[v][i]).c_str(),
" \n"[i == n - 1]);
}
#line 1 "test/graph/scc.test.cpp"
// competitive-verifier: PROBLEM https://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=GRL_1_C
#line 2 "prelude.hpp"
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using vi = vector<int>;
using vvi = vector<vector<int>>;
using vll = vector<ll>;
using vvll = vector<vector<ll>>;
using vc = vector<char>;
#define rep2(i, m, n) for (auto i = (m); i < (n); i++)
#define rep(i, n) rep2(i, 0, n)
#define repr2(i, m, n) for (auto i = (n); i-- > (m);)
#define repr(i, n) repr2(i, 0, n)
#define all(x) begin(x), end(x)
auto ndvec(int n, auto e) { return vector(n, e); }
auto ndvec(int n, auto ...e) { return vector(n, ndvec(e...)); }
auto comp_key(auto&& f) { return [&](auto&& a, auto&& b) { return f(a) < f(b); }; }
auto& max(const auto& a, const auto& b) { return a < b ? b : a; }
auto& min(const auto& a, const auto& b) { return b < a ? b : a; }
#if __cpp_lib_ranges
namespace R = std::ranges;
namespace V = std::views;
#endif
#line 3 "graph/traits.hpp"
struct unit_edge {
int to;
operator int() const { return to; }
int w() const { return 1; }
};
template <class Weight>
struct weighted_edge {
int to;
Weight weight;
operator int() const { return to; }
Weight w() const { return weight; }
};
template <class Inner>
struct basic_graph {
using weight_type = void;
const Inner& inner;
basic_graph(const Inner& g) : inner(g) { }
template <class F>
void adj(int v, F f) const {
for (auto u : inner[v]) f(unit_edge{u});
}
int deg(int v) const { return inner[v].size(); }
};
template <class Inner, class Weight>
struct basic_weighted_graph {
using weight_type = Weight;
const Inner& inner;
basic_weighted_graph(const Inner& g) : inner(g) { }
template <class F>
void adj(int v, F f) const {
for (auto [u, w] : inner[v]) f(weighted_edge<weight_type>{u, w});
}
int deg(int v) const { return inner[v].size(); }
};
template <class Inner>
struct graph_trait {
using weight_type = typename Inner::weight_type;
const Inner& g;
graph_trait(const Inner& g) : g(g) { }
int size() const { return g.size(); }
template <class F>
void adj(int v, F f) const {
g.adj(v, f);
}
decltype(auto) operator[](int v) const { return g[v]; }
};
template <class T>
constexpr bool is_weighted_v =
!is_same_v<typename graph_trait<T>::weight_type, void>;
template <class T>
using weight_t =
conditional_t<is_weighted_v<T>, typename graph_trait<T>::weight_type, int>;
template <class T>
using edge_t =
conditional_t<is_weighted_v<T>, weighted_edge<weight_t<T>>, unit_edge>;
template <size_t N>
struct graph_trait<vector<int>[N]> : basic_graph<vector<int>[N]> {
using basic_graph<vector<int>[N]>::basic_graph;
int size() const { return N; }
};
template <>
struct graph_trait<vector<vector<int>>> : basic_graph<vector<vector<int>>> {
using basic_graph<vector<vector<int>>>::basic_graph;
int size() const { return this->inner.size(); }
};
template <size_t N, class Weight>
struct graph_trait<vector<pair<int, Weight>>[N]>
: basic_weighted_graph<vector<pair<int, Weight>>[N], Weight> {
using basic_weighted_graph<
vector<pair<int, Weight>>[N], Weight>::basic_weighted_graph;
int size() const { return N; }
};
template <class Weight>
struct graph_trait<vector<vector<pair<int, Weight>>>>
: basic_weighted_graph<vector<vector<pair<int, Weight>>>, Weight> {
using basic_weighted_graph<
vector<vector<pair<int, Weight>>>, Weight>::basic_weighted_graph;
int size() const { return this->inner.size(); }
};
#line 3 "range.hpp"
template <class It>
struct range : pair<It, It> {
using pair<It, It>::pair;
It begin() const { return this->first; }
It end() const { return this->second; }
It cbegin() const { return begin(); }
It cend() const { return end(); }
int size() const { return this->second - this->first; }
};
#line 4 "graph/csr.hpp"
template <size_t>
struct stdin_reader;
template <class Weight = void>
class csr_graph {
private:
struct directed_t {};
public:
using weight_type = Weight;
csr_graph() = default;
template <class It>
csr_graph(int n, It e, It e_last) : n(n), m(distance(e, e_last)) {
init<false>(e, e_last);
}
template <size_t Size = 1 << 26>
csr_graph(int n, int m, stdin_reader<Size>& read) : n(n), m(m) {
auto e = read_e(read);
init<false>(all(e));
}
template <class It>
static csr_graph directed(int n, It e, It e_last) {
return csr_graph(directed_t{}, n, e, e_last);
}
template <size_t Size = 1 << 26>
static csr_graph directed(int n, int m, stdin_reader<Size>& read) {
return csr_graph(directed_t{}, n, m, read);
}
template <size_t Size = 1 << 26>
static csr_graph tree(int n, stdin_reader<Size>& read) {
return csr_graph(n, n - 1, read);
}
template <size_t Size = 1 << 26>
static csr_graph tree(stdin_reader<Size>& read) {
int n = read;
return csr_graph(n, n - 1, read);
}
int size() const { return n; }
range<typename vector<edge_t<csr_graph>>::iterator> operator[](int v) const {
return {ls[v], rs[v]};
}
int deg(int v) { return rs[v] - ls[v]; }
template <class F>
void adj(int v, F f) const {
for_each(ls[v], rs[v], f);
}
private:
template <class It>
csr_graph(directed_t, int n, It e, It e_last) : n(n), m(distance(e, e_last)) {
init<true>(e, e_last);
}
template <size_t Size = 1 << 26>
csr_graph(directed_t, int n, int m, stdin_reader<Size>& read) : n(n), m(m) {
auto e = read_e(read);
init<true>(all(e));
}
vector<typename vector<edge_t<csr_graph>>::iterator> ls, rs;
int n, m;
vector<edge_t<csr_graph>> es;
template <bool OneBased = true, size_t Size = 1 << 26>
auto read_e(stdin_reader<Size>& read) {
using E = conditional_t<is_weighted_v<csr_graph>, tuple<int, int, Weight>,
pair<int, int>>;
vector<E> res(m);
for (auto& e : res) {
read(e);
if (OneBased) get<0>(e)--, get<1>(e)--;
}
return res;
}
template <bool Directed, class It>
void init(It e, It e_last) {
if (!Directed) m *= 2;
es.resize(m);
ls.resize(n), rs.resize(n);
vector<int> sz(n);
for (auto it = e; it != e_last; it++) {
int from = get<0>(*it), to = get<1>(*it);
sz[from]++;
if (!Directed) sz[to]++;
}
partial_sum(all(sz), sz.begin());
rep(v, n) ls[v] = rs[v] = es.begin() + sz[v];
for (auto it = e; it != e_last; it++) {
int from = get<0>(*it), to = get<1>(*it);
if constexpr (is_weighted_v<csr_graph>)
*--ls[from] = edge_t<csr_graph>{to, get<2>(*it)};
else
*--ls[from] = edge_t<csr_graph>{to};
if (!Directed) {
if constexpr (is_weighted_v<csr_graph>)
*--ls[to] = edge_t<csr_graph>{from, get<2>(*it)};
else
*--ls[to] = edge_t<csr_graph>{from};
}
}
}
};
#line 3 "graph/bellman_ford.hpp"
// (fail, dist)
template <class G>
pair<bool, vector<weight_t<G>>> bellman_ford(G& graph, int s) {
const weight_t<G> inf = numeric_limits<weight_t<G>>::max();
graph_trait<G> g(graph);
vector<weight_t<G>> dist(g.size(), inf);
dist[s] = 0;
bool success = false;
rep(t, g.size()) {
bool updated = false;
rep(v, g.size()) if (dist[v] != inf) g.adj(v, [&](auto&& e) {
if (dist[e.to] > dist[v] + e.w())
updated = true,
dist[e.to] = dist[v] + e.w();
});
if (!updated) {
success = true;
break;
}
}
for (auto& d : dist) if (d >= inf / 2) d = numeric_limits<weight_t<G>>::max();
return {!success, move(dist)};
}
#line 3 "arith/sat.hpp"
template <class T, class U>
auto sat_add(T a, U b) {
using V = common_type_t<T, U>;
V res;
return __builtin_add_overflow((V)a, (V)b, &res)
? (a < 0 ? numeric_limits<V>::min() : numeric_limits<V>::max())
: res;
}
template <class T, class U>
auto sat_sub(T a, U b) {
using V = common_type_t<T, U>;
V res;
return __builtin_sub_overflow((V)a, (V)b, &res)
? (a < 0 ? numeric_limits<V>::min() : numeric_limits<V>::max())
: res;
}
template <class T, class U>
auto sat_mul(T a, U b) {
using V = common_type_t<T, U>;
V res;
return __builtin_mul_overflow((V)a, (V)b, &res)
? ((a < 0) == (b < 0) ? numeric_limits<V>::max()
: numeric_limits<V>::min())
: res;
}
#line 4 "graph/ford_fulkerson.hpp"
template <class G>
vector<vector<weight_t<G>>> ford_fulkerson(const G& graph) {
const weight_t<G> inf = numeric_limits<weight_t<G>>::max();
graph_trait<G> g(graph);
vector<vector<weight_t<G>>> res(g.size(), vector<weight_t<G>>(g.size(), inf));
rep(v, g.size()) {
res[v][v] = weight_t<G>(0);
g.adj(v, [&](auto&& e) { res[v][e.to] = e.w(); });
}
rep(k, g.size()) rep(u, g.size()) rep(v, g.size())
res[u][v] = min(res[u][v], sat_add(res[u][k], res[k][v]));
rep(u, g.size()) rep(v, g.size())
res[u][v] = res[u][v] >= inf / 2 ? inf : res[u][v];
return res;
}
#line 3 "graph/scc.hpp"
template <class G>
class scc {
public:
scc(const G& graph) : g(graph), id_(g.size()), n_cpnts(0) {
vector<char> visited(g.size(), false);
vector<int> post_ord;
post_ord.reserve(g.size());
vector<vector<int>> rev_graph(g.size());
auto dfs = [&](auto&& f, int v) -> void {
visited[v] = true;
g.adj(v, [&](int u) {
rev_graph[u].push_back(v);
if (!visited[u]) f(f, u);
});
post_ord.push_back(v);
};
rep(v, g.size()) if (!visited[v]) dfs(dfs, v);
reverse(all(post_ord));
fill(all(visited), false);
auto dfs2 = [&](auto&& f, int v) -> void {
visited[v] = true;
id_[v] = n_cpnts;
for (auto u : rev_graph[v])
if (!visited[u]) f(f, u);
};
for (auto v : post_ord)
if (!visited[v]) dfs2(dfs2, v), n_cpnts++;
}
// which component v belongs to
int operator()(int v) const { return id_[v]; }
int group_of(int v) const { return id_[v]; }
int n_groups() const { return n_cpnts; }
vector<vector<int>> groups() const {
vector<vector<int>> res(n_cpnts);
rep(v, g.size()) res[id_[v]].push_back(v);
return res;
}
template <class G1 = G, enable_if_t<!is_weighted_v<G1>>* = nullptr>
vector<vector<vector<int>>> components() const {
vector<int> v;
return components(v);
}
template <class G1 = G, enable_if_t<!is_weighted_v<G1>>* = nullptr>
vector<vector<vector<int>>> components(vector<int>& mapping) const {
vector<int> sizes(n_cpnts, 0);
mapping.resize(g.size());
rep(v, g.size()) mapping[v] = sizes[id_[v]]++;
vector<vector<vector<int>>> res(n_cpnts);
rep(i, n_cpnts) res[i].resize(sizes[i]);
rep(v, g.size()) g.adj(v, [&](int u) {
if (id_[v] == id_[u]) res[id_[v]][mapping[v]].push_back(mapping[u]);
});
return res;
}
template <class G1 = G, enable_if_t<is_weighted_v<G1>>* = nullptr>
vector<vector<vector<pair<int, weight_t<G>>>>> components() const {
vector<int> v;
return components(v);
}
template <class G1 = G, enable_if_t<is_weighted_v<G1>>* = nullptr>
vector<vector<vector<pair<int, weight_t<G>>>>> components(
vector<int>& mapping) const {
vector<int> sizes(n_cpnts, 0);
mapping.resize(g.size());
rep(v, g.size()) mapping[v] = sizes[id_[v]]++;
vector<vector<vector<pair<int, weight_t<G>>>>> res(n_cpnts);
rep(i, n_cpnts) res[i].resize(sizes[i]);
rep(v, g.size()) g.adj(v, [&](auto&& e) {
if (id_[v] == id_[e.to])
res[id_[v]][mapping[v]].emplace_back(mapping[e.to], e.w());
});
return res;
}
template <class G1 = G, enable_if_t<!is_weighted_v<G1>>* = nullptr>
vector<vector<int>> contract() const {
vector<vector<int>> res(n_cpnts);
rep(v, g.size()) g.adj(v, [&](int u) {
if (id_[v] != id_[u]) res[id_[v]].push_back(id_[u]);
});
return res;
}
template <class G1 = G, enable_if_t<is_weighted_v<G1>>* = nullptr>
vector<vector<pair<int, weight_t<G>>>> contract() const {
vector<vector<pair<int, weight_t<G>>>> res(n_cpnts);
rep(v, g.size()) g.adj(v, [&](auto&& e) {
if (id_[v] != id_[e.to]) res[v].emplace_back(e.to, e.w());
});
return res;
}
private:
graph_trait<G> g;
vector<int> id_;
int n_cpnts;
};
#line 7 "test/graph/scc.test.cpp"
int n, m;
vector<pair<int, ll>> G[100];
int main() {
scanf("%d%d", &n, &m);
rep(_, m) {
int u, v;
int w;
scanf("%d%d%d", &u, &v, &w);
G[u].emplace_back(v, w);
}
scc scc(G);
for (auto& vs : scc.groups())
if (bellman_ford(G, vs[0]).first) return printf("NEGATIVE CYCLE\n"), 0;
auto d = ford_fulkerson(G);
rep(v, n) rep(i, n) printf(
"%s%c", d[v][i] == LONG_LONG_MAX ? "INF" : to_string(d[v][i]).c_str(),
" \n"[i == n - 1]);
}
Env | Name | Status | Elapsed | Memory |
---|---|---|---|---|
g++-12 | 00_sample_00.in |
![]() |
27 ms | 9 MB |
g++-12 | 00_sample_01.in |
![]() |
25 ms | 9 MB |
g++-12 | 00_sample_02.in |
![]() |
13 ms | 8 MB |
g++-12 | 01_small_00.in |
![]() |
25 ms | 9 MB |
g++-12 | 01_small_01.in |
![]() |
13 ms | 8 MB |
g++-12 | 02_corner_00.in |
![]() |
25 ms | 9 MB |
g++-12 | 02_corner_01.in |
![]() |
25 ms | 9 MB |
g++-12 | 02_corner_02.in |
![]() |
25 ms | 9 MB |
g++-12 | 02_corner_03.in |
![]() |
13 ms | 8 MB |
g++-12 | 02_corner_04.in |
![]() |
25 ms | 9 MB |
g++-12 | 02_corner_05.in |
![]() |
25 ms | 9 MB |
g++-12 | 02_corner_06.in |
![]() |
25 ms | 9 MB |
g++-12 | 03_medium_00.in |
![]() |
25 ms | 9 MB |
g++-12 | 03_medium_01.in |
![]() |
13 ms | 9 MB |
g++-12 | 04_dag_00.in |
![]() |
25 ms | 9 MB |
g++-12 | 04_dag_01.in |
![]() |
26 ms | 9 MB |
g++-12 | 04_dag_02.in |
![]() |
26 ms | 9 MB |
g++-12 | 04_dag_03.in |
![]() |
27 ms | 9 MB |
g++-12 | 04_dag_04.in |
![]() |
28 ms | 9 MB |
g++-12 | 05_ring_00.in |
![]() |
26 ms | 9 MB |
g++-12 | 05_ring_01.in |
![]() |
26 ms | 9 MB |
g++-12 | 05_ring_02.in |
![]() |
27 ms | 9 MB |
g++-12 | 05_ring_03.in |
![]() |
27 ms | 9 MB |
g++-12 | 05_ring_04.in |
![]() |
26 ms | 9 MB |
g++-12 | 06_grid_00.in |
![]() |
25 ms | 9 MB |
g++-12 | 06_grid_01.in |
![]() |
25 ms | 9 MB |
g++-12 | 06_grid_02.in |
![]() |
25 ms | 9 MB |
g++-12 | 06_grid_03.in |
![]() |
26 ms | 9 MB |
g++-12 | 06_grid_04.in |
![]() |
26 ms | 9 MB |
g++-12 | 07_complete_00.in |
![]() |
25 ms | 9 MB |
g++-12 | 07_complete_01.in |
![]() |
26 ms | 9 MB |
g++-12 | 07_complete_02.in |
![]() |
28 ms | 9 MB |
g++-12 | 07_complete_03.in |
![]() |
29 ms | 10 MB |
g++-12 | 07_complete_04.in |
![]() |
30 ms | 10 MB |
g++-12 | 08_random_00.in |
![]() |
14 ms | 9 MB |
g++-12 | 08_random_01.in |
![]() |
14 ms | 9 MB |
g++-12 | 08_random_02.in |
![]() |
26 ms | 9 MB |
g++-12 | 08_random_03.in |
![]() |
26 ms | 9 MB |
g++-12 | 08_random_04.in |
![]() |
26 ms | 9 MB |
g++-12 | 08_random_05.in |
![]() |
26 ms | 9 MB |
g++-12 | 08_random_06.in |
![]() |
26 ms | 9 MB |
g++-12 | 08_random_07.in |
![]() |
27 ms | 9 MB |
g++-12 | 08_random_08.in |
![]() |
27 ms | 9 MB |
g++-12 | 09_maximum_00.in |
![]() |
26 ms | 9 MB |
g++-12 | 09_maximum_01.in |
![]() |
27 ms | 9 MB |
g++-12 | 09_maximum_02.in |
![]() |
32 ms | 10 MB |
g++-12 | 09_maximum_03.in |
![]() |
28 ms | 9 MB |
g++-12 | 09_maximum_04.in |
![]() |
15 ms | 9 MB |
g++-12 | 09_maximum_05.in |
![]() |
27 ms | 10 MB |
g++-12 | 09_maximum_06.in |
![]() |
26 ms | 9 MB |