Cây
Cây là đồ thị liên thông không có chu trình với đỉnh và cạnh.
Khái niệm cơ bản
Cây có gốc (rooted tree) là cây trong đó một đỉnh được chọn làm gốc.
- Cha (parent): đỉnh liền kề gần gốc hơn
- Con (children): các đỉnh liền kề xa gốc hơn
- Lá (leaf): đỉnh không có con
- Độ sâu (depth): khoảng cách từ gốc,
- Chiều cao (height): độ sâu lớn nhất trong cây
- Cây con của (subtree): gồm và toàn bộ hậu duệ của
Duyệt cây (DFS)
const int MAXN = 2e5 + 5;
vector<int> adj[MAXN];
int par[MAXN], dep[MAXN];
void dfs(int u, int p) {
par[u] = p;
for (int v : adj[u])
if (v != p) {
dep[v] = dep[u] + 1;
dfs(v, u);
}
}
// dep[root] = 0; dfs(root, -1);
DFS in/out time (Euler Tour)
Gán thời điểm vào tin[u] và ra tout[u] khi DFS thì cây con của trở thành đoạn liên tục [tin[u], tout[u]] trên mảng, nên truy vấn/cập nhật cây con quy về truy vấn đoạn với Fenwick hoặc Segment Tree. Chi tiết (kiểm tra tổ tiên, truy vấn đường đi gốc-đỉnh, các dạng Euler tour, DFS không đệ quy): xem trang Euler tour trên cây.
Đường kính cây
Đường đi dài nhất giữa hai đỉnh bất kỳ. Tìm bằng hai lần BFS:
- BFS từ đỉnh bất kỳ → tìm đỉnh xa nhất
- BFS từ → tìm đỉnh xa nhất
- Đường kính =
pair<int,int> farthest(int src, int n) {
vector<int> dist(n+1, -1);
queue<int> q;
q.push(src); dist[src] = 0;
int far = src;
while (!q.empty()) {
int u = q.front(); q.pop();
for (int v : adj[u])
if (dist[v] == -1) {
dist[v] = dist[u] + 1;
q.push(v);
if (dist[v] > dist[far]) far = v;
}
}
return {far, dist[far]};
}
auto [u, d1] = farthest(1, n);
auto [v, diameter] = farthest(u, n);
Tổ tiên chung thấp nhất (LCA)
là tổ tiên chung sâu nhất của và ; khoảng cách hai đỉnh là . Các cách tính (binary lifting, Euler tour + sparse table cho truy vấn , Tarjan offline) và ứng dụng (tổng trên đường đi, hiệu trên cây): xem trang Tổ tiên chung thấp nhất (LCA). Cài đặt binary lifting chi tiết: Binary Lifting.
Các trang chi tiết: lộ trình học
Nhóm Cây gồm 18 trang con. Gợi ý thứ tự học từ nền tảng đến nâng cao:
1. Cấu trúc nền tảng (học trước tiên)
| Trang | Mục đích chính | Độ phức tạp |
|---|---|---|
| Heap / Hàng đợi ưu tiên | Lấy min/max động, hàng đợi ưu tiên | /thao tác |
| Cây nhị phân tìm kiếm (BST) | Tập hợp có thứ tự (set/map) |
trung bình |
| Fenwick Tree (BIT) | Prefix sum + cập nhật điểm | |
| Segment Tree | Truy vấn + cập nhật đoạn (lazy) | |
| Trie | Lưu/tìm xâu; 01-Trie cho XOR |
2. BST cân bằng / nâng cao
| Trang | Mục đích chính |
|---|---|
| Treap | BST ngẫu nhiên, split/merge, implicit treap |
| Splay Tree | BST tự cân bằng amortized, thao tác trên dãy |
3. Kỹ thuật truy vấn trên cây
| Trang | Mục đích chính |
|---|---|
| Euler tour trên cây | Duỗi cây thành mảng, truy vấn cây con bằng BIT/Segment Tree |
| LCA | Tổ tiên chung thấp nhất: binary lifting, Euler tour + RMQ, Tarjan offline |
| Binary Lifting | LCA, tổ tiên thứ , /truy vấn |
| Heavy-Light Decomposition | Truy vấn/cập nhật trên đường đi |
| Centroid Decomposition | Đếm/đường đi theo phân rã trọng tâm |
| DSU on Tree | Gộp thông tin cây con (small-to-large) |
| Virtual Tree | Nén cây theo tập đỉnh quan trọng |
4. Segment Tree nâng cao
| Trang | Mục đích chính |
|---|---|
| Persistent Segment Tree | Truy vấn lịch sử, -th trên đoạn |
| Segment Tree Beats | Cập nhật min/max trên đoạn |
| Li Chao Tree | Bao lồi đường thẳng, tối ưu DP |
5. Cây động
| Trang | Mục đích chính |
|---|---|
| Link-Cut Tree | Rừng cây động, link/cut, truy vấn đường đi |
Bình luận