Skip to content
2 changes: 2 additions & 0 deletions .verify-helper/timestamps.remote.json
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,8 @@
"tests/library_checker_aizu_tests/graphs/dijkstra_lib_checker.test.cpp": "2025-08-14 10:27:46 -0600",
"tests/library_checker_aizu_tests/graphs/directed_cycle.test.cpp": "2026-01-17 13:05:42 -0700",
"tests/library_checker_aizu_tests/graphs/enumerate_triangles.test.cpp": "2025-08-06 16:18:37 -0600",
"tests/library_checker_aizu_tests/graphs/euler_walk_directed.test.cpp": "2026-02-26 13:17:25 -0700",
"tests/library_checker_aizu_tests/graphs/euler_walk_undirected.test.cpp": "2026-02-26 13:17:25 -0700",
"tests/library_checker_aizu_tests/graphs/hopcroft_karp_aizu.test.cpp": "2025-12-11 21:47:53 +0000",
"tests/library_checker_aizu_tests/graphs/hopcroft_karp_lib_checker.test.cpp": "2025-12-11 21:47:53 +0000",
"tests/library_checker_aizu_tests/graphs/mst.test.cpp": "2026-01-22 10:08:22 -0700",
Expand Down
28 changes: 28 additions & 0 deletions library/graphs/euler_path.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
#pragma once
//! @code
//! vector<basic_string<array<int, 2>>> adj(n);
//! rep(i, 0, m) {
//! int u, v;
//! cin >> u >> v;
//! u--, v--;
//! adj[u] += {v, i};
//! }
//! vector<pii> path = euler_path(adj, m, source);
//! @endcode
//! @time O(n + m)
//! @space O(n + m)
vector<pii> euler_path(auto& adj, int m, int s) {
vi vis(m);
vector<pii> path;
auto dfs = [&](auto&& self, int u, int eu) -> void {
while (!empty(adj[u])) {
auto [v, ev] = adj[u].back();
adj[u].pop_back();
if (!vis[ev]) vis[ev] = 1, self(self, v, ev);
}
path.emplace_back(u, eu);
};
dfs(dfs, s, -1);
ranges::reverse(path);
return path;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
#define PROBLEM \
"https://judge.yosupo.jp/problem/eulerian_trail_directed"
#include "../template.hpp"
#include "../../../library/graphs/euler_path.hpp"
int main() {
cin.tie(0)->sync_with_stdio(0);
int t;
cin >> t;
while (t--) {
int n, m;
cin >> n >> m;
vector<vector<pii>> adj(n);
vi deg(n);
int s = -1;
rep(i, 0, m) {
int u, v;
cin >> u >> v;
s = u;
adj[u].emplace_back(v, i);
deg[u]++;
deg[v]--;
}
if (*max_element(all(deg)) >= 2) {
cout << "No" << '\n';
continue;
}
if (ranges::count(deg, 1) >= 2) {
cout << "No" << '\n';
continue;
}
auto it = ranges::find(deg, 1);
if (it != end(deg)) s = it - begin(deg);
else if (s == -1) s = 0;
vector<pii> res = euler_path(adj, m, s);
if (ssize(res) != m + 1) {
cout << "No" << '\n';
continue;
}
cout << "Yes" << '\n';
rep(i, 0, sz(res)) cout << res[i].first << ' ';
cout << '\n';
rep(i, 1, sz(res)) cout << res[i].second << ' ';
cout << '\n';
}
return 0;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
#define PROBLEM \
"https://judge.yosupo.jp/problem/eulerian_trail_undirected"
#include "../template.hpp"
#include "../../../library/graphs/euler_path.hpp"
int main() {
cin.tie(0)->sync_with_stdio(0);
int t;
cin >> t;
while (t--) {
int n, m;
cin >> n >> m;
vector<vector<pii>> adj(n);
vi deg(n);
int s = -1;
rep(i, 0, m) {
int u, v;
cin >> u >> v;
s = u;
adj[u].emplace_back(v, i);
adj[v].emplace_back(u, i);
deg[u] ^= 1;
deg[v] ^= 1;
}
if (ranges::count(deg, 1) > 2) {
cout << "No" << '\n';
continue;
}
auto it = ranges::find(deg, 1);
if (it != end(deg)) s = it - begin(deg);
else if (s == -1) s = 0;
vector<pii> res = euler_path(adj, m, s);
if (ssize(res) != m + 1) {
cout << "No" << '\n';
continue;
}
cout << "Yes" << '\n';
rep(i, 0, sz(res)) cout << res[i].first << ' ';
cout << '\n';
rep(i, 1, sz(res)) cout << res[i].second << ' ';
cout << '\n';
}
return 0;
}