TJALG - Tìm TPLT mạnh

Tags: tarjan, dfs, dp, graph

Problem

https://vn.spoj.com/problems/TJALG

https://oj.vnoi.info/problem/TJALG

Cho đồ thị G(V,E) có hướng n (1 <= n <= 10^4)  đỉnh m (1 <= m <= 10^5) cung, Hãy đếm số thành phần liên thông mạnh của G.

Input

  • Dòng đầu tiên là n,m.
  • M dòng tiếp theo mô tả một cung của G.

Output

Gồm một dòng duy nhất là số TPLT mạnh.

Example

Input  
  
3 2  
1 2  
2 3  
  
Output  
3  

Input
3 3  
1 2  
2 3  
3 1  
  
Output  
1

Các bạn có thê tham khảo thuật toán ở đây: **Tarjan Algorithm**


Tutorial

Thuật toán Tarjan: (thuật này quan trọng, có liên quan đến cầu khớp với cùng một tư tưởng, cần hiểu được 1 số định nghĩa về cung ngược xuôi chéo, chốt và một số định lí liên quan, nên đọc Tài liệu chuyên tin quyển 1)

Mô hình thuật toán như sau:

Thứ nhất duyệt các đỉnh, nếu chưa thăm thì gọi dfs(u) tại đỉnh đó.

Trong thủ tục dfs(u), ta xét các đỉnh kề với u. Sau khi dfs xong thì kiểm tra xem u có là chốt không, nếu là chốt thì xuất ra thành phần liên thông chốt u.

Kiểm tra u là chốt bằng kĩ thuật như: Trong khi dfs(u), ta đánh số thứ tự cho u, tức là thứ tự dfs đến u, gọi là num[u]. Đồng thời tại thêm mảng low[u] với low[u] là thứ tự nhỏ nhất trong khi duyệt cây dfs gôc u, nếu low[u] < num[u] thì có đường đi lên các tiền bối của u nên u không là chốt.

Trong trường hợp ngược lại, u là chốt. Cách tính low[u] chỉ đơn giản là cực tiểu hóa nó trong quá trình duyệt cây dfs gôc u.

Với u là chốt, thì để tìm các nút trong TPLT mạnh chốt u, ta sử dụng một stack khi dfs đến một đỉnh k nào thì đẩy k vào stack. Lúc tìm thì chỉ việc pop ra đến khi pop đên u, tức chấm dứt TPLT mạnh chốt u.


Submission

TJALG.cpp