Skip to content

Commit 6c332cb

Browse files
committed
add transpose, can call spfa / dijkstra directly, can recover path directly from pre
1 parent 3cc24c6 commit 6c332cb

File tree

2 files changed

+33
-13
lines changed

2 files changed

+33
-13
lines changed

cp-algo/graph/base.hpp

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,17 @@ namespace cp_algo::graph {
1313
using incidence_list = structures::stack_union<edge_index>;
1414
graph(int n, int v0 = 0): v0(v0), adj(n) {}
1515

16+
graph transpose() const {
17+
static_assert(mode == directed, "transpose is only defined for directed graphs");
18+
graph<edge_t, mode> gt(n(), v0);
19+
for(auto v: nodes()) {
20+
for(auto e: outgoing(v)) {
21+
node_index u = edge(e).to;
22+
gt.add_edge(u, edge(e).backedge(v));
23+
}
24+
}
25+
return gt;
26+
}
1627
void add_edge(node_index u, edge_t e) {
1728
adj.push(u, (edge_index)size(E));
1829
E.push_back(e);
@@ -67,7 +78,7 @@ namespace cp_algo::graph {
6778
}
6879
}
6980
static edge_index opposite_idx(edge_index e) {
70-
static_assert(mode == undirected, "opposite_index is only defined for undirected graphs");
81+
static_assert(mode == undirected, "opposite_idx is only defined for undirected graphs");
7182
return e ^ 1;
7283
}
7384
private:

cp-algo/graph/shortest_path.hpp

Lines changed: 21 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -111,33 +111,42 @@ namespace cp_algo::graph {
111111
return context;
112112
}
113113

114+
template<weighted_graph_type graph>
115+
shortest_path_context dijkstra(graph const& g, node_index s) {
116+
return sssp_impl<dijkstra_context>(g, s);
117+
}
118+
template<weighted_graph_type graph>
119+
shortest_path_context spfa(graph const& g, node_index s) {
120+
return sssp_impl<spfa_context>(g, s);
121+
}
122+
114123
template<weighted_graph_type graph>
115124
shortest_path_context single_source_shortest_path(graph const& g, node_index s) {
116125
bool negative_edges = false;
117126
for (auto e: g.edges()) {
118127
negative_edges |= e.w < 0;
119128
}
120-
if (negative_edges) {
121-
return sssp_impl<spfa_context>(g, s);
122-
} else {
123-
return sssp_impl<dijkstra_context>(g, s);
124-
}
129+
return negative_edges ? spfa(g, s) : dijkstra(g, s);
125130
}
126131

127-
template<weighted_graph_type graph>
128-
std::optional<std::pair<int64_t, std::vector<edge_index>>> shortest_path(graph const& g, node_index s, node_index t) {
129-
auto [dist, pre] = single_source_shortest_path(g, s);
130-
if (dist[t] == shortest_path_context::inf) {
131-
return std::nullopt;
132-
}
132+
std::vector<edge_index> recover_path(auto const& pre, node_index s, node_index t) {
133133
std::vector<edge_index> path;
134134
node_index v = t;
135135
while(v != s) {
136136
path.push_back(pre[v].e);
137137
v = pre[v].u;
138138
}
139139
std::ranges::reverse(path);
140-
return {{dist[t], path}};
140+
return path;
141+
}
142+
143+
template<weighted_graph_type graph>
144+
std::optional<std::pair<int64_t, std::vector<edge_index>>> shortest_path(graph const& g, node_index s, node_index t) {
145+
auto [dist, pre] = single_source_shortest_path(g, s);
146+
if (dist[t] == shortest_path_context::inf) {
147+
return std::nullopt;
148+
}
149+
return {{dist[t], recover_path(pre, s, t)}};
141150
}
142151
}
143152
#endif // CP_ALGO_GRAPH_SHORTEST_PATH_HPP

0 commit comments

Comments
 (0)