10#include <unordered_set>
11#include <unordered_map>
29 auto adjacency_list = std::vector<std::vector<std::pair<int, int>>>(n);
30 for (
auto &&edge : edges)
35 adjacency_list[from].emplace_back(to, weight);
37 return adjacency_list;
54 auto adjacency_list = std::vector<std::vector<int>>(n);
55 for (
auto &&edge : edges)
59 adjacency_list[from].push_back(to);
60 adjacency_list[to].push_back(from);
62 return adjacency_list;
79 auto adjacency_list = std::vector<std::vector<std::pair<int, int>>>(n);
80 for (
auto &&edge : edges)
85 adjacency_list[from].emplace_back(to, weight);
86 adjacency_list[to].emplace_back(from, weight);
88 return adjacency_list;
105 auto adjacency_list = std::vector<std::vector<int>>(n);
106 for (
auto &&edge : edges)
110 adjacency_list[from].push_back(to);
112 return adjacency_list;
126 static void breadth_first_search(std::vector<std::vector<int>> &adjacency_list,
int root, std::function<
void(
int,
int)> callback)
128 auto visited = std::unordered_set<int>{};
129 auto q = std::queue<std::pair<int, int>>{};
133 auto [dist, node] = q.front();
136 if (visited.contains(node))
140 visited.insert(node);
142 callback(dist, node);
144 for (
auto adjacent_node : adjacency_list[node])
146 if (visited.contains(adjacent_node))
150 q.emplace(dist + 1, adjacent_node);
164 static void breadth_first_search(std::unordered_map<
int, std::vector<int>> &adjacency_list,
int root, std::function<
void(
int,
int)> callback)
166 auto visited = std::unordered_set<int>{};
167 auto q = std::queue<std::pair<int, int>>{};
171 auto [dist, node] = q.front();
174 if (visited.contains(node))
178 visited.insert(node);
180 callback(dist, node);
182 for (
auto adjacent_node : adjacency_list[node])
184 if (visited.contains(adjacent_node))
188 q.emplace(dist + 1, adjacent_node);
204 static void depth_first_search(std::vector<std::vector<int>> &adjacency_list,
int root, std::function<
void(
int,
int)> callback)
206 auto visited = std::unordered_set<int>{};
207 auto stack = std::stack<std::pair<int, int>>{};
208 stack.emplace(0, root);
209 while (!stack.empty())
211 auto [dist, node] = stack.top();
214 if (visited.contains(node))
218 visited.insert(node);
220 callback(dist, node);
222 for (
auto adjacent_node : adjacency_list[node])
224 if (visited.contains(adjacent_node))
228 stack.emplace(dist + 1, adjacent_node);
242 static int dijkstra(
int n,
const std::vector<std::vector<std::pair<int, int>>> &adjacency_list,
int src,
int dst)
245 std::vector<int> dist(n, std::numeric_limits<int>::max());
246 std::priority_queue<std::pair<int, int>, std::vector<std::pair<int, int>>, std::greater<>> pq;
253 int u = pq.top().second;
256 for (
const auto &neighbor : adjacency_list[u])
258 int v = neighbor.first;
259 int weight = neighbor.second;
261 if (dist[v] > dist[u] + weight)
263 dist[v] = dist[u] + weight;
264 pq.emplace(dist[v], v);
269 return dist[dst] == std::numeric_limits<int>::max() ? -1 : dist[dst];
291 std::unordered_map<int, std::stack<int>> adj;
292 std::unordered_map<int, int> in;
293 std::unordered_map<int, int> out;
294 for (
auto &&edge : edges)
303 int start = adj.begin()->first;
306 if (out[p.first] - in[p.first] == 1)
313 std::stack<int> current_path;
314 std::vector<int> circuit;
315 current_path.push(start);
317 while (!current_path.empty())
319 int current_vertex = current_path.top();
321 if (!adj[current_vertex].empty())
323 int next_vertex = adj[current_vertex].top();
324 adj[current_vertex].pop();
325 current_path.push(next_vertex);
329 circuit.push_back(current_vertex);
335 std::reverse(circuit.begin(), circuit.end());
352 std::unordered_map<int, bool> visited{};
355 visited.insert({p.first,
false});
358 std::vector<std::vector<int>> connectedComponents;
360 for (
auto &&p : visited)
364 std::vector<int> component;
367 visited[node] = true;
368 component.push_back(node);
370 connectedComponents.push_back(component);
374 return connectedComponents;
387 std::unordered_set<int> visited;
388 int component_count = 0;
390 auto dfs = [&](
int node,
auto &dfs_ref) ->
void {
391 visited.insert(node);
392 for (
int neighbor : adj.at(node))
394 if (visited.find(neighbor) == visited.end())
396 dfs_ref(neighbor, dfs_ref);
401 for (
const auto &p : adj)
404 if (visited.find(node) == visited.end())
413 return component_count;
Definition big_integer.hpp:14
static int dijkstra(int n, const std::vector< std::vector< std::pair< int, int > > > &adjacency_list, int src, int dst)
Definition graph.hpp:242
static std::vector< std::vector< int > > find_connected_components(std::unordered_map< int, std::vector< int > > &adj)
Definition graph.hpp:350
static std::vector< std::vector< int > > make_unweighted_directed_adjacency_list(int n, const std::vector< std::vector< int > > &edges)
Definition graph.hpp:103
static std::vector< std::vector< std::pair< int, int > > > make_weighted_directed_adjacency_list(int n, const std::vector< std::vector< int > > &edges)
Definition graph.hpp:27
static std::vector< std::vector< std::pair< int, int > > > make_weighted_undirected_adjacency_list(int n, const std::vector< std::vector< int > > &edges)
Definition graph.hpp:77
static int count_connected_components(const std::unordered_map< int, std::vector< int > > &adj)
Definition graph.hpp:385
static void depth_first_search(std::vector< std::vector< int > > &adjacency_list, int root, std::function< void(int, int)> callback)
Definition graph.hpp:204
static std::vector< int > find_euler_path_directed(const std::vector< std::vector< int > > &edges)
Definition graph.hpp:289
static void breadth_first_search(std::vector< std::vector< int > > &adjacency_list, int root, std::function< void(int, int)> callback)
Definition graph.hpp:126
static std::vector< std::vector< int > > make_unweighted_undirected_adjacency_list(int n, const std::vector< std::vector< int > > &edges)
Definition graph.hpp:52