You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: src/graph/euler_path.md
+71-67Lines changed: 71 additions & 67 deletions
Original file line number
Diff line number
Diff line change
@@ -66,97 +66,101 @@ The program below searches for and outputs a Eulerian loop or path in a graph, o
66
66
67
67
First, the program checks the degree of vertices: if there are no vertices with an odd degree, then the graph has an Euler cycle, if there are $2$ vertices with an odd degree, then in the graph there is only an Euler path (but no Euler cycle), if there are more than $2$ such vertices, then in the graph there is no Euler cycle or Euler path.
68
68
To find the Euler path (not a cycle), let's do this: if $V1$ and $V2$ are two vertices of odd degree, then just add an edge $(V1, V2)$, in the resulting graph we find the Euler cycle (it will obviously exist), and then remove the "fictitious" edge $(V1, V2)$ from the answer.
69
-
We will look for the Euler cycle exactly as described above (non-recursive version), and at the same time at the end of this algorithm we will check whether the graph was connected or not (if the graph was not connected, then at the end of the algorithm some edges will remain in the graph, and in this case we need to print $-1$).
69
+
We will look for the Euler cycle exactly as described above (recursive version), and at the same time at the end of this algorithm we will check whether the graph was connected or not (if the graph was not connected, then at the end of the algorithm some edges will remain in the graph, and in this case we need to print $-1$).
70
70
Finally, the program takes into account that there can be isolated vertices in the graph.
71
71
72
-
Notice that we use an adjacency matrix in this problem.
73
-
Also this implementation handles finding the next with brute-force, which requires to iterate over the complete row in the matrix over and over.
74
-
A better way would be to store the graph as an adjacency list, and remove edges in $O(1)$ and mark the reversed edges in separate list.
75
-
This way we can achieve an $O(N)$ algorithm.
76
-
77
72
```cpp
78
-
intmain() {
79
-
int n;
80
-
vector<vector<int>> g(n, vector<int>(n));
81
-
// reading the graph in the adjacency matrix
82
-
83
-
vector<int> deg(n);
84
-
for (int i = 0; i < n; ++i) {
85
-
for (int j = 0; j < n; ++j)
86
-
deg[i] += g[i][j];
87
-
}
73
+
vector<pair<int,int>> edges;
74
+
vector<vector<int>> g;
75
+
vector<bool> used;
76
+
vector<int> res;
77
+
78
+
voidadd_edge(int u, int v) {
79
+
int idx = (int) edges.size();
80
+
edges.emplace_back(u, v);
81
+
g[u].push_back(idx);
82
+
g[v].push_back(idx);
83
+
}
88
84
89
-
int first = 0;
90
-
while (first < n && !deg[first])
91
-
++first;
92
-
if (first == n) {
93
-
cout << -1;
94
-
return 0;
85
+
void dfs(int v) {
86
+
while (!g[v].empty()) {
87
+
int idx = g[v].back();
88
+
g[v].pop_back();
89
+
if (used[idx]) continue;
90
+
used[idx] = true;
91
+
auto [u, w] = edges[idx];
92
+
dfs(u ^ w ^ v);
95
93
}
94
+
res.push_back(v);
95
+
}
96
96
97
+
int main() {
98
+
ios::sync_with_stdio(0);
99
+
cin.tie(0);
100
+
int n, m;
101
+
cin >> n >> m;
102
+
edges.clear();
103
+
g.assign(n, vector<int> ());
104
+
used.assign(m + 1, false);
105
+
res.clear();
106
+
for (int i = 0; i < m; i++) {
107
+
int u, v;
108
+
cin >> u >> v;
109
+
u--, v--;
110
+
add_edge(u, v);
111
+
}
97
112
int v1 = -1, v2 = -1;
98
113
bool bad = false;
99
-
for (int i = 0; i < n; ++i) {
100
-
if (deg[i] & 1) {
101
-
if (v1 == -1)
114
+
for (int i = 0; i < n; i++) {
115
+
if ((int) g[i].size() % 2) {
116
+
if (v1 == -1) {
102
117
v1 = i;
103
-
else if (v2 == -1)
118
+
} else if (v2 == -1) {
104
119
v2 = i;
105
-
else
120
+
} else {
106
121
bad = true;
122
+
}
107
123
}
108
124
}
109
-
110
-
if (v1 != -1)
111
-
++g[v1][v2], ++g[v2][v1];
112
-
113
-
stack<int> st;
114
-
st.push(first);
115
-
vector<int> res;
116
-
while (!st.empty()) {
117
-
int v = st.top();
118
-
int i;
119
-
for (i = 0; i < n; ++i)
120
-
if (g[v][i])
121
-
break;
122
-
if (i == n) {
123
-
res.push_back(v);
124
-
st.pop();
125
-
} else {
126
-
--g[v][i];
127
-
--g[i][v];
128
-
st.push(i);
129
-
}
125
+
int first = 0;
126
+
while (first < n && g[first].empty()) {
127
+
first++;
128
+
}
129
+
if (bad || (v1 != -1 && v2 == -1) || first == n) {
0 commit comments