Hướng dẫn giải của Bedao OI Contest 1 - Đếm cầu


Chỉ dùng lời giải này khi không có ý tưởng, và đừng copy-paste code từ lời giải này. Hãy tôn trọng người ra đề và người viết lời giải.
Nộp một lời giải chính thức trước khi tự giải là một hành động có thể bị ban.

Tác giả: DeMen100ms

Lời giải mặc định độc giả đã biết và học về cầu (bridge) và Bridge Tree.

Ta sẽ dựng Bridge Tree của đồ thị. Vậy ta sẽ xem truy vấn trên Bridge Tree hoạt động thế nào.

Gọi:

  • ~LCA(u, v):~ Cha chung thấp nhất của ~u~ và ~v~.
  • ~d(u, v):~ Số cạnh trên đường đi ~u \rightarrow v~.
  • ~inter(a, b, c, d):~ Số cạnh chung của hai đường đi ~a \rightarrow b~ và ~c \rightarrow d~.

Gọi ~A', B', C', D'~ lần lượt là các nút nằm trên Bridge Tree đại diện cho ~A, B, C, D~. Vậy khi thêm một cạnh nối ~A - B~, đồng nghĩa với việc xóa hết tất cả các cạnh từ ~A' \rightarrow B'~ trên Bridge Tree và đáp án lúc này ~d(C', D')~.

Như vậy, đáp án cho một truy vấn sẽ là: ~d(C', D') - inter(A', B', C', D')~ trên Bridge Tree ban đầu.

Truy vấn ~d(C', D')~ có thể giải quyết bằng ~LCA~ cơ bản, nên ta sẽ tìm cách trả lời truy vấn tìm số cạnh chung.

Gọi ~u = LCA(A', B'), v = LCA(C', D')~.

Ta có: ~inter(A', B', C', D') = inter(u, A', v, C') + inter(u, A', v, D') + inter(u, B', v, C') + inter(u, B', v, D')~.

Lúc này các đường đi cần xét là các đường thẳng từ ~LCA~ đi xuống, nên ta có thể dễ dàng tính ~inter()~ bằng cách chia một vài trường hợp.

Độ phức tạp: ~O(n \log{n})~.

Code mẫu: https://ideone.com/E0515h


Bình luận

Hãy đọc nội quy trước khi bình luận.


Không có bình luận tại thời điểm này.