Mục lục Một số khái niệm cơ bản về đồ thị. Đếm số vùng liên thông. Liệt kê các vùng liên thông. Tìm vùng liên thông có nhiều đỉnh nhất.
Liệt kê các đỉnh đến được từ đỉnh S. Tìm đường đi từ đỉnh S đến đỉnh T. Đường đi từ S qua nhiều đảo nhất. Tham quan K đảo.
Hành trình từ S tới T khi vài đảo bị phong tỏa. Các vùng liên thông có tổng lớn nhất. Vùng nguyên tố lớn nhất. Vùng có tổng chi phí nhỏ hơn hoặc bằng S.
Vé miễn phí. Đường đi trên đồ thị có hướng. Đường đi từ S tới T và ngược lại. Đường truyền an toàn.
Điểm đến an toàn.109 skkn Một số khái niệm cơ bản về đồ thị Một đồ thị kí hiệu là G = (V,E) Trong đó: V là tập các đỉnh của đồ thị. Kí hiệu |V| = N là số đỉnh của đồ thị. E là tập các cạnh của đồ thị. Kí hiệu |E| = M là số cạnh của đồ thị.
Đỉnh: Đỉnh biểu diễn các đối tượng trong đồ thị, thường được đánh dấu bằng các số 1, 2,… hoặc kí hiệu bằng các chữ cái in thường u,v,… Cạnh: Cạnh nối đỉnh x với đỉnh y là một tập gồm hai phần tử (x,y). (x,y) thường được vẽ dưới dạng một đoạn thẳng nối hai đỉnh. Cạnh có hướng (cung): Là một cặp đỉnh có thứ tự. Trong mỗi cặp có thứ tự đó, đỉnh thứ nhất được gọi là đỉnh đầu, đỉnh thứ hai là đỉnh cuối.
Cạnh vô hướng: Không quan tâm đến hướng và coi hai đỉnh như nhau. Khuyên: Là một cạnh nối một đỉnh với chính nó. Hai cạnh song song: Là hai cạnh cùng nối hai đỉnh u, v. Đồ thị có hướng: 2 skkn Là đồ thị mà tất cả các cạnh trong đồ thị đều có hướng.
Đồ thị vô hướng: Là đồ thị mà tất cả các cạnh trong đồ thị đều vô hướng. Đơn đồ thị: Là đồ thị không có khuyên và không có cạnh song song. Đa đồ thị: Là đồ thị không phải là đơn đồ thị. Bậc: Trong đồ thị vô hướng, bậc của đỉnh v trong đồ thị G, ký hiệu dG(u), là số cạnh liên thuộc với v, trong đó, khuyên được tính hai lần.
Ta có định lí: Giả sử G=(V,E) là đồ thị vô hướng, khi đó tổng các bậc đỉnh trong V sẽ bằng 2 lần số cạnh. Hệ quả: Trong đồ thị vô hướng, số đỉnh bậc lẻ là chẵn. Trong đồ thị có hướng, ta định nghĩa bán bậc ra của u là số cung đi ra khỏi nó, kí hiệu d+G(u), bán bậc vào của u là số cung đi vào đỉnh đó, kí hiệu d-G(u). Giả sử G=(V, E) là đồ thị có hướng, khi đó tổng các bán bậc vào bằng tổng các bán bậc ra và bằng số cung của đồ thị.
Đường đi và chu trình: Một dãy các đỉnh P = (p0, p1, …, pk) sao cho (Pi-1, Pi) ∊ E, ∀i: 1 ≤ i ≤ k được gọi là một đường đi. Một đường đi là chu trình khi p0 = pk. Liên thông: Một đồ thị vô hướng là liên thông nếu tồn tại đường đi giữa hai cặp đỉnh bất kì thuộc đồ thị. 3 skkn Một đồ thị có hướng là liên thông yếu nếu phiên bản vô hướng của đồ thị đó là liên thông.
Biểu diễn đồ thị trên máy tính Có nhiều cách để biểu diễn đồ thị trên máy tính, tùy thuộc vào tính chất của đồ thị hoặc thuật toán áp dụng với đồ thị… Ta cũng có thể lưu kèm theo các thông tin như trọng số, giá trị phù hợp với từng cạnh. * Biển diễn đồ thị theo ma trận kề: Tạo một ma trận A kích thước n*n trong đó n là số đỉnh của đồ thị. Nếu là đơn đồ thị, vô hướng không trọng số: a[u][v] = 0 nếu không có cạnh nối hai đỉnh u, v. a[u][v] = a[v][u] = 1 nếu có cạnh nối hai đỉnh u, v.
Nếu đồ thị là đa đồ thị vô hướng không trọng số, tương tự, chỉ khác ta có thể gán a[u][v] = số cạnh nối u và v. Nếu đồ thị vô hướng có trọng số thì chúng ta thay a[u][v] = 1 và a[v] [u]=1 đó thành a[u][v] = a[v][u] = c (với c chính là trọng số của cạnh đó). Nếu đồ thì có hướng, dữ liệu đề bài nói rõ cạnh đi từ u đến v thì chỉ gán a[u][v] = 1 và không gán chiều ngược lại là được. Định nghĩa và gán tùy theo lập trình viên hiểu là vô hướng hay có hướng, đơn đồ thị hay đa đồ thị.
* Một trong các thuật toán tìm kiếm trên đồ thị là: DFS 4 skkn 1. Đếm số vùng liên thông.* Vùng liên thông trong đồ thị là tập hợp các đỉnh mà từ một đỉnh bất kỳ có đường đi trực tiếp hoặc gián tiếp đến các đỉnh khác trong tập hợp đó. Cho đồ thị vô hướng có N đỉnh, M cạnh. Hãy đếm số lượng vùng liên thông trong đồ thị.
Dữ liệu: Vào từ file văn bản DFSVLT.INP gồm: Dòng 1: Ghi số nguyên N và M (M, N ≤ 3000). M dòng tiếp theo, mỗi dòng ghi số nguyên dương u và v thể hiện có đường đi giữa hai đỉnh u và v (u, v ≤ N). Kết quả: Ghi ra file văn bản DFSVLT.OUT số lượng vùng liên thông.OUT 12 7 5 12 (gồm 3 vùng 25 bên, đỉnh 7, 26 đỉnh 8) 6 10 34 9 11 9 12 Thuật toán: * Ta biểu diễn đồ thị theo ma trận kề: Lưu các cạnh vào mảng a có N hàng, N cột với N là số đỉnh của đồ thị. Khi đó, a[u,v] = 0 khi không đường đi trực tiếp từ u tới v.
a[u,v] = a[v,u] = 1 khi có đường đi trực tiếp từ u tới v. 5 skkn * Tư tưởng giải thuật Duyệt theo chiều sâu: Ban đầu các đỉnh fre[i] = True. Duyệt đến đỉnh thứ i, đánh dấu i đã đi đến (fre[i] = False). Ta thực hiện duyệt tất cả các đỉnh j đang free và có đường đi trực tiếp từ i đến j thì ta Duyệt ( j ).
Tới đỉnh j, ta lặp lại việc duyệt như ở bước trên. Lưu ý: Với mỗi đỉnh i, ta sẽ đi đến được tất cả các đỉnh có đường đi trực tiếp hoặc gián tiếp tới i. Như vậy, mỗi lần duyệt (i) xong ta sẽ thu được một vùng liên thông. Ở bài này, ta tăng biến đếm số lượng vùng liên thông lên.
Độ phức tạp thuật toán: O(M + N) ? Code chương trình tham khảo: 6 skkn 7 skkn Code mẫu C++: Code1 8 skkn Code mẫu C++ code 2: 9 skkn 10 skkn Code 3 tham khảo: 11 skkn 12 skkn 2. Liệt kê các vùng liên thông.* Vùng liên thông trong đồ thị là tập hợp các đỉnh mà từ một đỉnh bất kỳ có đường đi trực tiếp hoặc gián tiếp đến các đỉnh khác trong tập hợp đó. Cho đồ thị vô hướng có N đỉnh, M cạnh. Hãy liệt kê các vùng liên thông trong đồ thị.
Trong mỗi vùng các đỉnh được sắp xếp thành dãy tăng. Mỗi vùng liên thông trên một hàng. Mỗi số cách nhau một dấu cách. Dữ liệu: Vào từ file văn bản DFSNVLT.INP gồm: Dòng 1: Ghi số nguyên N và M (M, N ≤ 3000).
M dòng tiếp theo, mỗi dòng ghi số nguyên dương u và v thể hiện có đường đi giữa hai đỉnh u và v (u, v ≤ N). Kết quả: Ghi ra file văn bản DFSNVLT.OUT gồm nhiều dòng là các vùng liên thông trong đồ thị. Trong mỗi vùng các đỉnh được sắp xếp thành dãy tăng. Mỗi số cách nhau một dấu cách, mỗi vùng liên thông trên một hàng.OUT 12 7 1 2 5 6 10 12 34 25 7 26 8 6 10 9 11 12 34 9 11 9 12 Thuật toán: Ta duyệt qua tất cả các đỉnh, nếu i đang free thì ta Duyệt (i).
13 skkn Thủ tục Duyệt (i) ngoài việc đánh dấu i đã đi đến, ta lưu i vào mảng C có K phần tử. Mỗi lần Duyệt xong một vùng liên thông, ta đưa vùng đó ra và khởi tạo lại K=0; Duyệt theo chiều sâu luôn tạo ra các vùng liên thông theo thứ tự từ điển. Do đó cần phải sắp xếp lại mảng C ? Độ phức tạp thuật toán: O(M + N) ? Code chương trình tham khảo: 14 skkn Do các đỉnh cần sắp xếp lại, nên bạn cần code thêm đoạn sắp xếp mảng C trước khi ghi ra kết quả. 15 skkn Code 1 tham khảo: 16 skkn Code 2 tham khảo: 17 skkn Code 3 tham khảo: 18 skkn 19 skkn 20 skkn Code 4 tham khảo: 21 skkn 3.
Tìm vùng liên thông có nhiều đỉnh nhất.* Vùng liên thông trong đồ thị là tập hợp các đỉnh mà từ một đỉnh bất kỳ có đường đi trực tiếp hoặc gián tiếp đến các đỉnh khác trong tập hợp đó. Cho đồ thị vô hướng có N đỉnh, M cạnh. Hãy liệt kê vùng liên thông có nhiều đỉnh nhất trong đồ thị. Mỗi số cách nhau một dấu cách, nếu có nhiều vùng liên thông có cùng số lượng đỉnh nhiều nhất thì đưa ra vùng liên thông có thứ tự từ điển nhỏ nhất.
Dữ liệu: Vào từ file văn bản DFSMVLT.INP gồm: Dòng 1: Ghi số nguyên N và M (M, N ≤ 3000). M dòng tiếp theo, mỗi dòng ghi số nguyên dương u và v thể hiện có đường đi giữa hai đỉnh u và v (u, v ≤ N). Kết quả: Ghi ra file văn bản DFSMVLT.OUT gồm: Dòng 1: Ghi số lượng đỉnh trong vùng liên thông tìm được. Dòng 2: Các đỉnh trong vùng liên thông tìm được, được sắp xếp thành dãy tăng.
Mỗi số cách nhau một dấu cách.OUT 12 7 5 12 1 2 5 6 10 25 26 6 10 34 9 11 9 12 Thuật toán: 22 skkn Ta duyệt qua tất cả các đỉnh, nếu i đang free thì ta Duyệt (i). Thủ tục Duyệt (i) ngoài việc đánh dấu i đã đi đến, ta lưu i vào mảng C có K phần tử. Mỗi lần Duyệt xong một vùng liên thông, ta cập nhật lại kmax và lưu mảng C sang mảng D và khởi tạo lại K = 0. Ta đưa kmax và mảng D sau khi sắp xếp ra.
Code chương trình tham khảo: 23 skkn Code 1 tham khảo: 24 skkn Code 2 tham khảo: 25 skkn 26 skkn Code 2 tham khảo: 27 skkn Code 3 tham khảo: 28 skkn 29 skkn 4. Liệt kê các đỉnh đến được từ đỉnh S.* Cho đồ thị vô hướng có N đỉnh, M cạnh. Hãy liệt kê các đỉnh đi đến được từ đỉnh S. Dữ liệu: Vào từ file văn bản DFSLVLT.INP gồm: Dòng 1: Ghi số nguyên dương N, M và S (M, N ≤ 3000, S ≤ N).
M dòng tiếp theo, mỗi dòng ghi số nguyên dương u và v thể hiện có đường đi giữa hai đỉnh u và v (u, v ≤ N). Kết quả: Ghi ra file văn bản DFSLVLT.