1. Trang chủ
  2. » Cao đẳng - Đại học

bµi to¸n lan ch­¬ng ii bµi to¸n lan bµi to¸n lan lµ mét bµi to¸n c¬ b¶n cã nhiòu øng dông trong viöc gi¶i mét sè ®ò thi häc sinh giái tin häc nã th­êng ®­îc m« t¶ d­íi m« h×nh cña lý thuyõt ®å thþ víi

3 8 0

Đang tải... (xem toàn văn)

THÔNG TIN TÀI LIỆU

Thông tin cơ bản

Định dạng
Số trang 3
Dung lượng 7,89 KB

Các công cụ chuyển đổi và chỉnh sửa cho tài liệu này

Nội dung

Th«ng thêng, trong qu¸ tr×nh duyÖt c¸c miÒn liªn th«ng, ta muèn ghi nhËn l¹i mçi phÇn tö lµ thuéc miÒn nµo.[r]

Trang 1

chơng ii bài toán lan

Bài toán lan là một bài toán cơ bản có nhiều ứng dụng trong việc giải một số đề

thi học sinh giỏi Tin học Nó thờng đợc mô tả dới mô hình của lý thuyết đồ thị với nhiều

tên gọi khác nhau: bài toán tìm kiếm, bài toán duyệt, bài toán đi thăm, Ta có thể mô

phỏng bài toán này nh sau:

Xét một tập hợp các phần tử nào đấy, trên đó đã định nghĩa một quan hệ 2-ngôi

giữa các phần tử gọi là quan hệ kề: thế nào là phần tử B kề với phần tử A Dới mô hình đồ thị, các phần tử đợc gọi là các nút hay các đỉnh, và nếu đỉnh B kề với đỉnh A thì ta nói có một cạnh đi từ A đến B Quan hệ kề có thể là đối xứng hay không đối xứng Nếu quan hệ này là đối xứng thì cạnh xác định tơng ứng là vô hớng (nghĩa là cạnh đi từ A đến B cũng chính là cạnh đi từ B đến A), trái lại, cạnh là có hớng Quan hệ kề đợc mở rộng theo luật

bắc cầu thành quan hệ lan:

- mọi phần tử A xem nh lan đợc tới chính nó,

- nếu B kề với A thì A lan đợc tới B,

- nếu A lan đợc tới B, đồng thời B lan đợc tới C thì A lan đợc tới C

Trong lý thuyết đồ thị, ngời ta thờng nói khi A lan đợc tới B là từ A có đờng đi tới

B, hay từ A có thể đi thăm B Bài toán đặt ra là xác định tập hợp tất cả các phần tử có thể

lan đợc từ một phần tử xuất phát đã cho

Có hai phơng pháp lan chủ yếu: lan theo chiều rộng và lan theo chiều sâu.

1 Lan theo chiều rộng

T tởng cơ bản của phơng pháp này là từ những phần tử đã đợc lan, ta lan dần sang

các phần tử khác theo từng mức kề với phần tử đang xét Có hai thao tác đợc lặp lại trong

quá trình lan: lấy một phần tử từ tập hợp các phần tử đã đợc lan làm điểm xuất phát và kết nạp các phần tử kề với phần tử này vào tập hợp các phần tử đã đợc lan Dĩ nhiên, để vòng lặp kết thúc đợc, những phần tử đợc lấy ra phải loại khỏi tập hợp đang xét và những phần

tử thêm vào phải là những phần tử cha đợc kết nạp lần nào Quá trình lan sẽ kết thúc khi tập hợp các phần tử đã đợc lan đang xét là rỗng và khi ấy, những phần tử nào đã đợc xét kết nạp là những phần tử đợc lan từ phần tử ban đầu

Về mặt dữ liệu, tập hợp các phần tử đã đợc lan đợc tổ chức nh một hàng đợi, trong

đó có hai thao tác: lấy ra một phần tử ở đầu hàng đợi và kết nạp một phần tử vào cuối hàng đợi Thuật toán lan theo chiều rộng, bắt đầu từ phần tử S, có thể mô tả bằng đoạn

ch-ơng trình PASCAL (mô phỏng) dới đây:

Enter;

Init;

Append_To_Queue(S);

While <Hàng đợi khác rỗng> do

begin

Extract_From_Queue(X);

For <Y cha đợc kết nạp và Y kề với X> do

Append_To_Queue(Y);

end;

Result;

trong đó, thủ tục Enter nhập các thông tin về quan hệ kề và phần tử xuất phát, thủ tục Init

khởi tạo các giá trị ban đầu bao gồm khởi tạo hàng đợi rỗng và đánh dấu cha kết nạp cho

mọi phần tử, thủ tục Append_To_Queue(X) kết nạp phần tử X vào hàng đợi và đánh dấu

đã kết nạp cho phần tử này, thủ tục Extract_From_Queue(X) lấy phần tử X ra khỏi hàng

đợi và cuối cùng, thủ tục Result xử lý kết quả đã thu đợc.

Trang 2

Có thể có nhiều cách tổ chức một hàng đợi Đơn giản hơn cả (khi bộ nhớ cho phép), hàng đợi đợc tổ chức nh một mảng Q[1 N] lấy giá trị trên các phần tử, trong đó N

là số phần tử đợc xét Để quản lý hàng đợi này, ta thêm vào các biến nguyên first, last để

chỉ các vị trí đầu và cuối hàng đợi Nh vậy, số phần tử hiện có của hàng đợi đợc xác định

bởi last-first+1 Các thao tác trên hàng đợi lúc này là:

- khởi tạo hàng đợi rỗng:

first := 1; last := 0;

- lấy X ra khỏi hàng đợi:

X := Q[first]; first := first+1;

- kết nạp X vào hàng đợi:

last := last+1; Q[last] := X;

2 Lan theo chiều sâu

Khác với lan theo chiều rộng là lan theo từng mức kề (vì thế các phần tử đợc lan

theo mọi hớng), lan theo chiều sâu là lan theo một hớng đã chọn cho đến khi không lan

thêm đợc nữa thì lùi lại lan theo hớng khác Để quá trình lan là kết thúc, tất nhiên không

đợc lan lại những phần tử đã lan rồi Thực chất đây là phơng pháp quay lui để duyệt mọi

hớng lan có thể có và ta có thể dùng thủ tục đệ quy Depth_Expand(X) dới đây để mô tả việc lan theo chiều sâu từ X (kiểu của các phần tử đợc định nghĩa bởi tên Elements):

Procedure Depth_Expand(X: Elements);

Var Y: Elements;

Begin

<đánh dấu đã lan cho X>;

For <Y cha lan và Y kề với X> do Depth_Expand(Y);

End;

Việc dùng thủ tục đệ quy sẽ tổ chức lu trữ các thông tin của quá trình lan theo cơ

cấu ngăn xếp Bài toán lan bắt đầu từ S lúc này đợc giải theo mô hình sau:

Enter;

Init;

Depth_Expand(S);

Result;

trong đó các thủ tục Enter và Result đợc thiết kế giống nh trớc, thủ tục Init khởi tạo giá trị

cha đợc lan cho tất cả các phần tử

3 Miền liên thông

Nếu quan hệ kề cho trên tập hợp đang xét là đối xứng (khi đó đồ thị tơng ứng gọi

là vô hớng vì các cạnh của nó đều là vô hớng) - nghĩa là A kề với B kéo theo B kề với A (vì thế ngời ta thờng nói trong trờng hợp này là chúng kề nhau), thì tập hợp đang xét sẽ

đ-ợc chia thành những lớp rời nhau từng đôi và những lớp này phủ kín tập hợp đang xét, sao cho hai phần tử của cùng một lớp là lan đợc sang nhau và hai phần tử khác lớp là không

lan đợc sang nhau Ngời ta gọi mỗi lớp nh vậy là một miền liên thông hay ngắn gọn - một

miền - của quan hệ kề đã cho Nh vậy mỗi miền liên thông sẽ đợc xác định duy nhất bởi

một phần tử bất kỳ thuộc nó Mọi phần tử khác của miền sẽ đợc nhận bằng cách lan từ phần tử này Để duyệt các miền liên thông, cần đánh dấu những phần tử nào đã đợc lan,

và quá trình duyệt đợc tiến hành bằng cách bắt đầu từ những phần tử cha đánh dấu lan ra những phần tử khác Việc duyệt các miền liên thông có thể mô tả qua đoạn chơng trình: Init;

For <X thuộc tập hợp các phần tử> do

Trang 3

if <X cha đợc lan> then Expand(X);

trong đó Init là thủ tục khởi tạo giá trị cha đợc lan cho mọi phần tử và Expand(X) là thủ tục lan bắt đầu từ X Thủ tục Expand(X) có thể đợc thiết kế lan theo chiều rộng hoặc lan

theo chiều sâu nh đã trình bày Mỗi lần thực hiện thủ tục này là một lần một miền liên thông đợc xác định

Thông thờng, trong quá trình duyệt các miền liên thông, ta muốn ghi nhận lại mỗi phần tử là thuộc miền nào Để làm điều này, ngời ta thờng tổ chức một mảng nguyên L[ ], với các chỉ số chạy trên các phần tử, ghi nhận số hiệu miền của phần tử tơng ứng (các miền đợc đánh số hiệu 1, 2, ) Mảng này cũng dùng để ghi nhận phần tử tơng ứng

đã đợc lan hay cha với quy ớc L[X] = 0 nghĩa là X cha đợc lan Đoạn chơng trình trên đợc sửa lại chút ít nh sau:

Init; k := 0;

For <X thuộc tập hợp các phần tử> do

if L[X] = 0 then

begin

k = k+1;

Expand(X);

end;

trong đó việc gán giá trị cha đợc lan cho mọi X trong Init đợc thay bởi việc gán 0 cho mọi L[X], và thao tác đánh dấu cho các phần tử đợc lan Y trong Expand(X) đợc thay bởi thao

tác gán giá trị k cho L[Y] Sau đoạn chơng trình, biến k sẽ lu trữ số miền liên thông đã xác định

Chú ý rằng, với quan hệ kề không đối xứng (tơng ứng với đồ thị có hớng), không

có khái niệm miền liên thông nh đã trình bày

4 Các bài toán lan trên bảng

Các bài toán lan trên một bảng (vuông hay chữ nhật) là dạng thờng gặp nhất trong các đề thi hiện nay Một bảng đợc cấu tạo bởi các ô vuông xếp thành những dòng và những cột Mỗi ô vuông đợc xem nh một phần tử (hoặc đỉnh - nếu theo ngôn ngữ đồ thị)

Ngày đăng: 13/04/2021, 17:30

TÀI LIỆU CÙNG NGƯỜI DÙNG

TÀI LIỆU LIÊN QUAN

🧩 Sản phẩm bạn có thể quan tâm

w