Skip to content

Commit 76d1e3b

Browse files
chore: update minified library versions
1 parent dfe645f commit 76d1e3b

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

66 files changed

+150
-2691
lines changed

cp-algo/min/geometry/closest_pair.hpp

Lines changed: 2 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -4,25 +4,5 @@
44
#include "point.hpp"
55
#include <vector>
66
#include <map>
7-
namespace cp_algo::geometry{template<typename ftype>
8-
auto closest_pair(std::vector<point_t<ftype>>const&r){using point=point_t<ftype>;
9-
size_t n=size(r);
10-
int64_t md=1e18;
11-
for(size_t i=0;i<n/100;i++){auto A=random::rng()%n;
12-
auto B=random::rng()%n;
13-
if(A!=B){md=std::min(md,norm(r[A]-r[B]));
14-
if(md==0){return std::pair{A,B};}}}
15-
std::map<point,std::vector<size_t>>neigs;
16-
md=(int64_t)ceil(sqrt((double)md));
17-
for(size_t i=0;i<n;i++){neigs[r[i]/md].push_back(i);}
18-
size_t a=0,b=1;
19-
md=norm(r[a]-r[b]);
20-
for(auto&[p,id]:neigs){for(int dx:{-1,0,1}){for(int dy:{-1,0,1}){auto pp=p+point{dx,dy};
21-
if(!neigs.count(pp)){continue;}
22-
for(size_t i:neigs[pp]){for(size_t j:id){if(j==i){break;}
23-
int64_t cur=norm(r[i]-r[j]);
24-
if(cur<md){md=cur;
25-
a=i;
26-
b=j;}}}}}}
27-
return std::pair{a,b};}}
28-
#endif
7+
namespace cp_algo::geometry{template<typename ftype>auto closest_pair(std::vector<point_t<ftype>>const&r){using point=point_t<ftype>;size_t n=size(r);int64_t md=1e18;for(size_t i=0;i<n/100;i++){auto A=random::rng()%n;auto B=random::rng()%n;if(A!=B){md=std::min(md,norm(r[A]-r[B]));if(md==0){return std::pair{A,B};}}}std::map<point,std::vector<size_t>>neigs;md=(int64_t)ceil(sqrt((double)md));for(size_t i=0;i<n;i++){neigs[r[i]/md].push_back(i);}size_t a=0,b=1;md=norm(r[a]-r[b]);for(auto&[p,id]:neigs){for(int dx:{-1,0,1}){for(int dy:{-1,0,1}){auto pp=p+point{dx,dy};if(!neigs.count(pp)){continue;}for(size_t i:neigs[pp]){for(size_t j:id){if(j==i){break;}int64_t cur=norm(r[i]-r[j]);if(cur<md){md=cur;a=i;b=j;}}}}}}return std::pair{a,b};}}
8+
#endif

cp-algo/min/geometry/convex_hull.hpp

Lines changed: 2 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -5,17 +5,5 @@
55
#include <utility>
66
#include <vector>
77
#include <ranges>
8-
namespace cp_algo::geometry{template<typename ftype>
9-
std::vector<point_t<ftype>>convex_hull(std::vector<point_t<ftype>>r){using point=point_t<ftype>;
10-
std::ranges::sort(r);
11-
if(size(r)<=1||r[0]==r.back()){return empty(r)?r:std::vector{r[0]};}
12-
std::vector<point>hull={r[0]};
13-
for(int half:{0,1}){size_t base=size(hull);
14-
for(auto it:std::views::drop(r,1)){while(size(hull)>=base+1){point a=hull.back();
15-
if(point::ccw(it-a,end(hull)[-2]-a)){break;}else{hull.pop_back();}}
16-
hull.push_back(it);}
17-
std::ranges::reverse(r);
18-
std::ignore=half;}
19-
hull.pop_back();
20-
return hull;}}
21-
#endif
8+
namespace cp_algo::geometry{template<typename ftype>std::vector<point_t<ftype>>convex_hull(std::vector<point_t<ftype>>r){using point=point_t<ftype>;std::ranges::sort(r);if(size(r)<=1||r[0]==r.back()){return empty(r)?r:std::vector{r[0]};}std::vector<point>hull={r[0]};for(int half:{0,1}){size_t base=size(hull);for(auto it:std::views::drop(r,1)){while(size(hull)>=base+1){point a=hull.back();if(point::ccw(it-a,end(hull)[-2]-a)){break;}else{hull.pop_back();}}hull.push_back(it);}std::ranges::reverse(r);std::ignore=half;}hull.pop_back();return hull;}}
9+
#endif

cp-algo/min/geometry/point.hpp

Lines changed: 2 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -2,23 +2,5 @@
22
#define CP_ALGO_GEOMETRY_POINT_HPP
33
#include "../util/complex.hpp"
44
#include <iostream>
5-
namespace cp_algo::geometry{template<typename ftype>
6-
struct point_t:complex<ftype>{using Base=complex<ftype>;
7-
using Base::Base;
8-
point_t(Base const&t):Base(t){}
9-
auto operator<=>(point_t const&t)const{return std::pair{y(),-x()}<=>std::pair{t.y(),-t.x()};}
10-
ftype x()const{return Base::real();}
11-
ftype y()const{return Base::imag();}
12-
point_t cmul(point_t const&t)const{return conj(*this)*t;}
13-
ftype dot(point_t const&t)const{return cmul(t).x();}
14-
ftype cross(point_t const&t)const{return cmul(t).y();}
15-
static constexpr point_t O={0,0};
16-
int half()const{return*this<O?-1:*this==O?0:1;}
17-
static bool ccw(point_t const&a,point_t const&b){return a.cross(b)>0;}
18-
static bool ccw_abs(point_t const&a,point_t const&b){return std::tuple{a.half(),(ftype)0,norm(a)}<
19-
std::tuple{b.half(),a.cross(b),norm(b)};}
20-
void read(){ftype _x,_y;
21-
std::cin>>_x>>_y;
22-
*this={_x,_y};}
23-
void print()const{std::cout<<x()<<' '<<y()<<"\n";}};}
24-
#endif
5+
namespace cp_algo::geometry{template<typename ftype>struct point_t:complex<ftype>{using Base=complex<ftype>;using Base::Base;point_t(Base const&t):Base(t){}auto operator<=>(point_t const&t)const{return std::pair{y(),-x()}<=>std::pair{t.y(),-t.x()};}ftype x()const{return Base::real();}ftype y()const{return Base::imag();}point_t cmul(point_t const&t)const{return conj(*this)*t;}ftype dot(point_t const&t)const{return cmul(t).x();}ftype cross(point_t const&t)const{return cmul(t).y();}static constexpr point_t O={0,0};int half()const{return*this<O?-1:*this==O?0:1;}static bool ccw(point_t const&a,point_t const&b){return a.cross(b)>0;}static bool ccw_abs(point_t const&a,point_t const&b){return std::tuple{a.half(),(ftype)0,norm(a)}<std::tuple{b.half(),a.cross(b),norm(b)};}void read(){ftype _x,_y;std::cin>>_x>>_y;*this={_x,_y};}void print()const{std::cout<<x()<<' '<<y()<<"\n";}};}
6+
#endif

cp-algo/min/graph/base.hpp

Lines changed: 2 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -4,40 +4,5 @@
44
#include "concepts.hpp"
55
#include "../structures/stack_union.hpp"
66
#include <ranges>
7-
namespace cp_algo::graph{using edge_index=int;
8-
template<edge_type _edge_t=edge_base,graph_mode _mode=undirected>
9-
struct graph{using edge_t=_edge_t;
10-
static constexpr auto mode=_mode;
11-
using incidence_list=structures::stack_union<edge_index>;
12-
graph(int n,int v0=0):v0(v0),adj(n){}
13-
graph transpose()const{static_assert(mode==directed,"transpose is only defined for directed graphs");
14-
graph<edge_t,mode>gt(n(),v0);
15-
for(auto v:nodes()){for(auto e:outgoing(v)){gt.add_edge(edge(e).traverse(v),edge(e));}}
16-
return gt;}
17-
edge_index add_edge(node_index u,edge_t e){edge_index idx=(edge_index)size(E);
18-
E.push_back(e);
19-
adj.push(u,idx);
20-
if constexpr(mode==undirected){adj.push(e.traverse(u),idx);}
21-
return idx;}
22-
edge_index add_edge(node_index u,auto... Args){return add_edge(u,edge_t(u,Args...));}
23-
void read_edges(node_index m){adj.reserve(mode==undirected?2*m:m);
24-
for(edge_index i=0;i<m;i++){auto[u,e]=edge_t::read(v0);
25-
add_edge(u,e);}}
26-
auto outgoing(node_index v)const{return adj[v];}
27-
auto edges()const{return E|std::views::all;}
28-
auto nodes()const{return std::views::iota(node_index(0),n());}
29-
auto edge_indices()const{return std::views::iota(edge_index(0),m());}
30-
auto&&incidence_lists(this auto&&self){return self.adj;}
31-
auto&&edge(this auto&&self,edge_index e){return self.E[e];}
32-
node_index n()const{return(node_index)incidence_lists().size();}
33-
edge_index m()const{return(edge_index)edges().size();}
34-
private:node_index v0;
35-
big_vector<edge_t>E;
36-
incidence_list adj;};
37-
template<edge_type edge_t=edge_base>
38-
using digraph=graph<edge_t,directed>;
39-
template<weighted_edge_type edge_t=weighted_edge,graph_mode mode=undirected>
40-
using weighted_graph=graph<edge_t,mode>;
41-
template<weighted_edge_type edge_t=weighted_edge>
42-
using weighted_digraph=digraph<edge_t>;}
43-
#endif
7+
namespace cp_algo::graph{using edge_index=int;template<edge_type _edge_t=edge_base,graph_mode _mode=undirected>struct graph{using edge_t=_edge_t;static constexpr auto mode=_mode;using incidence_list=structures::stack_union<edge_index>;graph(int n,int v0=0):v0(v0),adj(n){}graph transpose()const{static_assert(mode==directed,"transpose is only defined for directed graphs");graph<edge_t,mode>gt(n(),v0);for(auto v:nodes()){for(auto e:outgoing(v)){gt.add_edge(edge(e).traverse(v),edge(e));}}return gt;}edge_index add_edge(node_index u,edge_t e){edge_index idx=(edge_index)size(E);E.push_back(e);adj.push(u,idx);if constexpr(mode==undirected){adj.push(e.traverse(u),idx);}return idx;}edge_index add_edge(node_index u,auto... Args){return add_edge(u,edge_t(u,Args...));}void read_edges(node_index m){adj.reserve(mode==undirected?2*m:m);for(edge_index i=0;i<m;i++){auto[u,e]=edge_t::read(v0);add_edge(u,e);}}auto outgoing(node_index v)const{return adj[v];}auto edges()const{return E|std::views::all;}auto nodes()const{return std::views::iota(node_index(0),n());}auto edge_indices()const{return std::views::iota(edge_index(0),m());}auto&&incidence_lists(this auto&&self){return self.adj;}auto&&edge(this auto&&self,edge_index e){return self.E[e];}node_index n()const{return(node_index)incidence_lists().size();}edge_index m()const{return(edge_index)edges().size();}private:node_index v0;big_vector<edge_t>E;incidence_list adj;};template<edge_type edge_t=edge_base>using digraph=graph<edge_t,directed>;template<weighted_edge_type edge_t=weighted_edge,graph_mode mode=undirected>using weighted_graph=graph<edge_t,mode>;template<weighted_edge_type edge_t=weighted_edge>using weighted_digraph=digraph<edge_t>;}
8+
#endif

cp-algo/min/graph/concepts.hpp

Lines changed: 2 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -2,25 +2,5 @@
22
#define CP_ALGO_GRAPH_CONCEPTS_HPP
33
#include "edge_types.hpp"
44
#include <type_traits>
5-
namespace cp_algo::graph{enum graph_mode{directed,undirected};
6-
template<typename T,typename=void>
7-
struct graph_traits:std::false_type{};
8-
template<typename T>
9-
struct graph_traits<T,std::void_t<typename T::edge_t,decltype(T::mode)>>:std::true_type{using edge_t=typename T::edge_t;
10-
static constexpr auto mode=T::mode;
11-
static constexpr bool is_directed=mode==directed;
12-
static constexpr bool is_undirected=mode==undirected;
13-
static constexpr bool is_weighted=weighted_edge_type<edge_t>;};
14-
template<typename G>
15-
concept graph_type=graph_traits<G>::value;
16-
template<typename G>
17-
concept digraph_type=graph_type<G>&&graph_traits<G>::is_directed;
18-
template<typename G>
19-
concept undirected_graph_type=graph_type<G>&&graph_traits<G>::is_undirected;
20-
template<typename G>
21-
concept weighted_graph_type=graph_type<G>&&graph_traits<G>::is_weighted;
22-
template<typename G>
23-
concept weighted_digraph_type=digraph_type<G>&&graph_traits<G>::is_weighted;
24-
template<typename G>
25-
concept weighted_undirected_graph_type=undirected_graph_type<G>&&graph_traits<G>::is_weighted;}
26-
#endif
5+
namespace cp_algo::graph{enum graph_mode{directed,undirected};template<typename T,typename=void>struct graph_traits:std::false_type{};template<typename T>struct graph_traits<T,std::void_t<typename T::edge_t,decltype(T::mode)>>:std::true_type{using edge_t=typename T::edge_t;static constexpr auto mode=T::mode;static constexpr bool is_directed=mode==directed;static constexpr bool is_undirected=mode==undirected;static constexpr bool is_weighted=weighted_edge_type<edge_t>;};template<typename G>concept graph_type=graph_traits<G>::value;template<typename G>concept digraph_type=graph_type<G>&&graph_traits<G>::is_directed;template<typename G>concept undirected_graph_type=graph_type<G>&&graph_traits<G>::is_undirected;template<typename G>concept weighted_graph_type=graph_type<G>&&graph_traits<G>::is_weighted;template<typename G>concept weighted_digraph_type=digraph_type<G>&&graph_traits<G>::is_weighted;template<typename G>concept weighted_undirected_graph_type=undirected_graph_type<G>&&graph_traits<G>::is_weighted;}
6+
#endif

cp-algo/min/graph/cycle.hpp

Lines changed: 2 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -3,19 +3,5 @@
33
#include "dfs.hpp"
44
#include "base.hpp"
55
#include <deque>
6-
namespace cp_algo::graph{template<graph_type graph>
7-
struct cycle_context:dfs_context<graph>{using base=dfs_context<graph>;
8-
using base::base;
9-
std::deque<edge_index>cycle;
10-
bool closed=false;
11-
int v0;
12-
void on_return_from_child(node_index v,edge_index e){if(!empty(cycle)&&!closed){cycle.push_front(e);
13-
closed|=v==v0;}}
14-
void on_back_edge(node_index v,edge_index e){if(empty(cycle)){v0=base::g->edge(e).traverse(v);
15-
base::done=true;
16-
closed=v==v0;
17-
cycle.push_front(e);}}};
18-
template<graph_type graph>
19-
std::pair<node_index,std::deque<edge_index>>find_cycle(graph const&g){auto context=dfs<cycle_context>(g);
20-
return{context.v0,context.cycle};}}
21-
#endif
6+
namespace cp_algo::graph{template<graph_type graph>struct cycle_context:dfs_context<graph>{using base=dfs_context<graph>;using base::base;std::deque<edge_index>cycle;bool closed=false;int v0;void on_return_from_child(node_index v,edge_index e){if(!empty(cycle)&&!closed){cycle.push_front(e);closed|=v==v0;}}void on_back_edge(node_index v,edge_index e){if(empty(cycle)){v0=base::g->edge(e).traverse(v);base::done=true;closed=v==v0;cycle.push_front(e);}}};template<graph_type graph>std::pair<node_index,std::deque<edge_index>>find_cycle(graph const&g){auto context=dfs<cycle_context>(g);return{context.v0,context.cycle};}}
7+
#endif

cp-algo/min/graph/dfs.hpp

Lines changed: 2 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -3,56 +3,5 @@
33
#include "base.hpp"
44
#include <variant>
55
#include <stack>
6-
namespace cp_algo::graph{enum node_state{unvisited,visiting,visited,blocked};
7-
template<graph_type graph>
8-
struct dfs_context{big_vector<node_state>state;
9-
graph const*g;
10-
bool done=false;
11-
dfs_context(graph const&g):state(g.n()),g(&g){}
12-
void on_enter(node_index){}
13-
void on_tree_edge(node_index,edge_index){}
14-
void on_return_from_child(node_index,edge_index){}
15-
void on_back_edge(node_index,edge_index){}
16-
void on_forward_cross_edge(node_index,edge_index){}
17-
void on_exit(node_index){}};
18-
template<template<typename>class Context,graph_type graph>
19-
Context<graph>dfs(graph const&g){Context<graph>context(g);
20-
auto const&adj=g.incidence_lists();
21-
struct frame{node_index v;
22-
[[no_unique_address]]std::conditional_t<
23-
undirected_graph_type<graph>,
24-
edge_index,std::monostate>ep;
25-
int sv;
26-
enum{INIT,PROCESS_EDGES,HANDLE_CHILD}state;};
27-
std::stack<frame>dfs_stack;
28-
for(auto root:g.nodes()){if(context.done)break;
29-
if(context.state[root]!=unvisited)continue;
30-
if constexpr(undirected_graph_type<graph>){dfs_stack.push({root,-1,0,frame::INIT});}else{dfs_stack.push({root,{},0,frame::INIT});}
31-
while(!empty(dfs_stack)){auto&f=dfs_stack.top();
32-
if(f.state==frame::INIT){context.state[f.v]=visiting;
33-
context.on_enter(f.v);
34-
f.sv=adj.head[f.v];
35-
f.state=frame::PROCESS_EDGES;
36-
continue;}
37-
if(f.state==frame::HANDLE_CHILD){auto e=adj.data[f.sv];
38-
f.sv=adj.next[f.sv];
39-
context.on_return_from_child(f.v,e);
40-
f.state=frame::PROCESS_EDGES;
41-
continue;}
42-
bool found_child=false;
43-
while(f.sv!=0&&!context.done){auto e=adj.data[f.sv];
44-
if constexpr(undirected_graph_type<graph>){if(f.ep==e){f.sv=adj.next[f.sv];
45-
continue;}}
46-
node_index u=g.edge(e).traverse(f.v);
47-
if(context.state[u]==unvisited){context.on_tree_edge(f.v,e);
48-
f.state=frame::HANDLE_CHILD;
49-
if constexpr(undirected_graph_type<graph>){dfs_stack.push({u,e,0,frame::INIT});}else{dfs_stack.push({u,{},0,frame::INIT});}
50-
found_child=true;
51-
break;}else if(context.state[u]==visiting){context.on_back_edge(f.v,e);}else if(context.state[u]==visited){context.on_forward_cross_edge(f.v,e);}
52-
f.sv=adj.next[f.sv];}
53-
if(found_child)continue;
54-
context.state[f.v]=visited;
55-
context.on_exit(f.v);
56-
dfs_stack.pop();}}
57-
return context;}}
58-
#endif
6+
namespace cp_algo::graph{enum node_state{unvisited,visiting,visited,blocked};template<graph_type graph>struct dfs_context{big_vector<node_state>state;graph const*g;bool done=false;dfs_context(graph const&g):state(g.n()),g(&g){}void on_enter(node_index){}void on_tree_edge(node_index,edge_index){}void on_return_from_child(node_index,edge_index){}void on_back_edge(node_index,edge_index){}void on_forward_cross_edge(node_index,edge_index){}void on_exit(node_index){}};template<template<typename>class Context,graph_type graph>Context<graph>dfs(graph const&g){Context<graph>context(g);auto const&adj=g.incidence_lists();struct frame{node_index v;[[no_unique_address]]std::conditional_t<undirected_graph_type<graph>,edge_index,std::monostate>ep;int sv;enum{INIT,PROCESS_EDGES,HANDLE_CHILD}state;};std::stack<frame>dfs_stack;for(auto root:g.nodes()){if(context.done)break;if(context.state[root]!=unvisited)continue;if constexpr(undirected_graph_type<graph>){dfs_stack.push({root,-1,0,frame::INIT});}else{dfs_stack.push({root,{},0,frame::INIT});}while(!empty(dfs_stack)){auto&f=dfs_stack.top();if(f.state==frame::INIT){context.state[f.v]=visiting;context.on_enter(f.v);f.sv=adj.head[f.v];f.state=frame::PROCESS_EDGES;continue;}if(f.state==frame::HANDLE_CHILD){auto e=adj.data[f.sv];f.sv=adj.next[f.sv];context.on_return_from_child(f.v,e);f.state=frame::PROCESS_EDGES;continue;}bool found_child=false;while(f.sv!=0&&!context.done){auto e=adj.data[f.sv];if constexpr(undirected_graph_type<graph>){if(f.ep==e){f.sv=adj.next[f.sv];continue;}}node_index u=g.edge(e).traverse(f.v);if(context.state[u]==unvisited){context.on_tree_edge(f.v,e);f.state=frame::HANDLE_CHILD;if constexpr(undirected_graph_type<graph>){dfs_stack.push({u,e,0,frame::INIT});}else{dfs_stack.push({u,{},0,frame::INIT});}found_child=true;break;}else if(context.state[u]==visiting){context.on_back_edge(f.v,e);}else if(context.state[u]==visited){context.on_forward_cross_edge(f.v,e);}f.sv=adj.next[f.sv];}if(found_child)continue;context.state[f.v]=visited;context.on_exit(f.v);dfs_stack.pop();}}return context;}}
7+
#endif

cp-algo/min/graph/dfs_time.hpp

Lines changed: 2 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -2,27 +2,5 @@
22
#define CP_ALGO_GRAPH_DFS_TIME_HPP
33
#include "dfs.hpp"
44
#include "base.hpp"
5-
namespace cp_algo::graph{template<graph_type graph>
6-
struct dfs_time_context:dfs_context<graph>{using base=dfs_context<graph>;
7-
big_vector<int>tin;
8-
int timer;
9-
dfs_time_context(graph const&g):base(g),tin(g.n()),timer(0){}
10-
void on_enter(node_index v){tin[v]=timer++;}};
11-
template<graph_type graph>
12-
struct dfs_time_range_context:dfs_time_context<graph>{using base=dfs_time_context<graph>;
13-
big_vector<int>tout;
14-
dfs_time_range_context(graph const&g):base(g),tout(g.n()){}
15-
void on_exit(node_index v){tout[v]=base::timer;}};
16-
template<graph_type graph>
17-
struct dfs_low_context:dfs_time_context<graph>{using base=dfs_time_context<graph>;
18-
big_vector<int>low;
19-
dfs_low_context(graph const&g):base(g),low(g.n()){}
20-
void on_enter(node_index v){base::on_enter(v);
21-
low[v]=base::tin[v];}
22-
void on_return_from_child(node_index v,edge_index e){node_index u=base::g->edge(e).traverse(v);
23-
low[v]=std::min(low[v],low[u]);}
24-
void on_back_edge(node_index v,edge_index e){node_index u=base::g->edge(e).traverse(v);
25-
low[v]=std::min(low[v],base::tin[u]);}
26-
void on_forward_cross_edge(node_index v,edge_index e){node_index u=base::g->edge(e).traverse(v);
27-
low[v]=std::min(low[v],base::tin[u]);}};}
28-
#endif
5+
namespace cp_algo::graph{template<graph_type graph>struct dfs_time_context:dfs_context<graph>{using base=dfs_context<graph>;big_vector<int>tin;int timer;dfs_time_context(graph const&g):base(g),tin(g.n()),timer(0){}void on_enter(node_index v){tin[v]=timer++;}};template<graph_type graph>struct dfs_time_range_context:dfs_time_context<graph>{using base=dfs_time_context<graph>;big_vector<int>tout;dfs_time_range_context(graph const&g):base(g),tout(g.n()){}void on_exit(node_index v){tout[v]=base::timer;}};template<graph_type graph>struct dfs_low_context:dfs_time_context<graph>{using base=dfs_time_context<graph>;big_vector<int>low;dfs_low_context(graph const&g):base(g),low(g.n()){}void on_enter(node_index v){base::on_enter(v);low[v]=base::tin[v];}void on_return_from_child(node_index v,edge_index e){node_index u=base::g->edge(e).traverse(v);low[v]=std::min(low[v],low[u]);}void on_back_edge(node_index v,edge_index e){node_index u=base::g->edge(e).traverse(v);low[v]=std::min(low[v],base::tin[u]);}void on_forward_cross_edge(node_index v,edge_index e){node_index u=base::g->edge(e).traverse(v);low[v]=std::min(low[v],base::tin[u]);}};}
6+
#endif

0 commit comments

Comments
 (0)