Cho một đồ thị vô hướng với b nút và a cạnh. Ta cần tìm số cạnh tối thiểu cần thêm để đồ thị có chu trình Euler (Euler Circuit).
Ví dụ, với đồ thị như hình dưới đây:

Kết quả sẽ là 1.
Thuật toán giải quyết
- Hàm
dfs(g, visit, odd_vert, degree, comp, v):- Đánh dấu
visit[v] := 1. - Nếu
degree[v] % 2 == 1thìodd_vert[comp] += 1. - Duyệt các đỉnh kề
ucủav: nếuvisit[u] == 0thì gọi đệ quydfs.
- Đánh dấu
- Từ hàm chính:
- Khởi tạo danh sách kề
g, mảngdegree,visit,odd_vert. - Đọc các cạnh, cập nhật
gvàdegree. - Khởi tạo
ans := 0,comp := 0, danh sáche(thành phần liên thông có đỉnh chẵn),o(thành phần liên thông có đỉnh lẻ). - Duyệt các đỉnh 1..n: nếu chưa thăm thì tăng
comp, gọidfs. Phân loại thànhehoặcodựa trênodd_vert[comp]. - Nếu
len(o) == 0vàlen(e) == 1: trả về 0. - Nếu
len(o) == 0: trả vềlen(e). - Nếu
len(e) != 0:ans += len(e). - Với mỗi thành phần trong
o:ans += odd_vert[i] // 2. - Trả về
ans.
- Khởi tạo danh sách kề
Ví dụ minh họa
def dfs(g, visit, odd_vert, degree, comp, v):
visit[v] = 1
if degree[v] % 2 == 1:
odd_vert[comp] += 1
for u in g[v]:
if visit[u] == 0:
dfs(g, visit, odd_vert, degree, comp, u)
def solve(n, m, s, d):
g = [[] for _ in range(n + 1)]
e = []
o = []
degree = [0] * (n + 1)
visit = [0] * (n + 1)
odd_vert = [0] * (n + 1)
for i in range(m):
g[s[i]].append(d[i])
g[d[i]].append(s[i])
degree[s[i]] += 1
degree[d[i]] += 1
ans = 0
comp = 0
for i in range(1, n + 1):
if visit[i] == 0:
comp += 1
dfs(g, visit, odd_vert, degree, comp, i)
if odd_vert[comp] == 0:
e.append(comp)
else:
o.append(comp)
if len(o) == 0 and len(e) == 1:
return 0
if len(o) == 0:
return len(e)
if len(e) != 0:
ans += len(e)
for i in range(len(o)):
ans += odd_vert[i] // 2
return ans
b = 3
a = 2
source = [1, 2]
destination = [2, 3]
print(solve(b, a, source, destination)) # 1
Đầu vào
b = 3, a = 2, source = [1, 2], destination = [2, 3]
Đầu ra
1