Professional Documents
Culture Documents
Đư NG Đi Và Chu Trình Euler
Đư NG Đi Và Chu Trình Euler
ĐỊNH NGHĨA 1 :
- Chu trình đơn trong G đi qua mỗi cạnh của nó một lần được gọi là chu trình Euler.
- Đường đi đơn trong G đi qua mỗi cạnh của nó một lần được gọi là đường đi Euler.
- Đồ thị được gọi là đồ thị thị Euler nếu nó có chu trình Euler, và gọi là đồ thị nửa Euler nếu nó có
đường đi Euler.
- Mọi đồ thị Euler đều là nửa Euler nhưng điều ngược lại không đúng.
Ví dụ 1: xác định đồ thị euler, nửa Euler trong các đồ thị vô hướng dưới đây
Đồ thị G3 không có chu trình nhưng có đường đi Euler a,c,d,e,b,a,b vì thế G3 là nửa Euler.
Ví dụ 2: Đồ thị có hướng nào dưới đây có chu trình Euler? Trong số những đồ thị không có đồ thị nào có
đường đi Euler
Đồ thị H2 có chu trình Euler : a,g,c,b,g,e,d,f,a. Cả H1 và H3 đều không có chu trình Euler. H3 có đường đi
Euler, cụ thể là c,d,b,c,a,b, nhưng H1 thì không.
- Đồ thị vô hướng liên thông G=(V,E) là đồ thị Euler khi và chỉ khi mọi đỉnh của G đều có bậc chẵn
- Cho đồ thị có hướng G liên thông và có hơn 1 đỉnh. Khi đó, G có chu trình Euler nếu và chỉ nếu G
cân bằng ( deg+(v)=deg-(v) với mọi đỉnh v)
Hệ quả : Đồ thị vô hướng liên thông G=(V,E) là đồ thị nửa Euler khi và chỉ khi nó không có quá hai
đỉnh bậc lẻ. Khi đó tìm được đường đi Euler có hai đầu đường đi Euler có hai đầu đường đi nằm ở
hai đỉnh bậc lẻ.
Ví dụ 3: Đồ thị vô hướng dưới đây có phải đồ thị Euler hay không ? Vì sao ?
Nhận thấy tất cả các đỉnh đều có bậc chẵn nên đây là đồ thị Euler với chu trình Euler là DEABCEBD.
Ví dụ 4: Đồ thị có hướng dưới đây có phải đồ thị Euler hay không ? Vì sao ?
Đồ thị này thỏa mãn deg+(v)=deg-(v) (với mọi đỉnh v) nên đây là đồ thị Euler. Chu trình Euler là
DEABCEBD.
Phát biểu bài toán : cho đa đồ thị vô hướng liên thông G gồm n đỉnh, m cạnh. Hãy tìm ra một chu
trình Euler của đồ thị?
Ý tưởng: Xuất phát từ một đỉnh, ta tùy ý theo các cạnh theo hai nguyên tắc :
Ví dụ 7 :
Với đồ thị trên, nếu xuất phát từ đỉnh 1, có hai cách chọn đỉnh để đi tiếp: sang 2 hoặc 3, giả sử
chọn 2 thì xóa cạnh (1,2) vừa đi qua. Từ chỉ có cách duy nhất là sang 4, nên cho dù (2,4) là cầu ta
cũng phải đi qua và xóa cạnh (2,4). Bây giờ đang đứng ở đỉnh 4 thì ta có 3 cách đi tiếp: sang 3,
sang 5 hoặc sang 6. Vì (4,3) là cầu nên ta sẽ không đi theo cạnh (4,3) mà sẽ đi theo (4,5) hoặc
(4,6). Nếu đi theo (4,5) và cứ tiếp tục đi như vậy, ta sẽ được chu trình Euler là
(1,2,4,5,7,8,6,4,3,1). Còn đi theo (4,6) sẽ được chu trình Euler là (1,2,4,6,8,7,5,4,3,1).
Ta sẽ cài đặt giải thuật bằng cách sử dụng một ma trận kề adj[u][v] để
biểu diễn đồ thị cho thuận tiện khi thực hiện thao tác xóa cạnh, ngoài
ra có thêm một hàm kiểm tra xem đồ thị có phải là đồ thị Euler hay
không.
from collections import deque
def enter():
n = int(input())
adj = [[0] * (n + 1) for _ in range(n + 1)]
deg = [0] * (n + 1)
while True:
try:
u, v, k = map(int, input().split())
adj[u][v] = adj[v][u] = k
deg[u] += k
deg[v] += k
except EOFError:
break
if cnt_comps > 1:
return False
return True
is_free = [True] * (n + 1)
path = deque()
path.append(v)
while path:
cur = path.popleft()
if cur == u:
break
adj[u][v] += 1
adj[v][u] += 1
return not is_free[u]
cur_vertex = 1
next_v = 0
circuit = [cur_vertex]
while True:
next_v = 0
for v in range(1, n + 1):
if adj[cur_vertex][v]:
next_v = v
if can_go_back(n, adj, cur_vertex, next_v):
break
if next_v != 0:
adj[cur_vertex][next_v] -= 1
adj[next_v][cur_vertex] -= 1
circuit.append(next_v)
cur_vertex = next_v
else:
break
for u in circuit:
print(u, end=' ')
if __name__ == "__main__":
n, adj, deg = enter()
fleury(n, adj, deg)