# G2. Passable Paths (hard version) link : https://codeforces.com/problemset/problem/1702/G2 tóm tắt đề : cho 1 cây, có q truy vấn, mỗi truy vấn cho 1 tập đỉnh và hỏi xem tập đó có tạo thành 1 đường đi đơn hay không. + suy nghĩ 1: nếu không tạo đường đi đơn thì rẽ nhánh, cần nghĩ điều kiện rẽ nhánh + suy nghĩ 2 : có thể add từ từ các node vào xem node vừa add có vi phạm quy tắc hay không nhận xét : cách làm dài và if else nhiều :::spoiler ```cpp= #include<bits/stdc++.h> #define pii pair<int, int> #define rep(i, a, b) for (int i = (a); i <= (b); ++i) #define rev(i, a, b) for (int i = (a); i >= (b); --i) #define X first #define Y second using namespace std; const int mxn = 2e5 + 5; int st[mxn], ed[mxn]; int par[18][mxn]; int lan, n, head, l, r; vector<int> adj[mxn]; void dfs(int u, int p) { st[u] = ++lan; par[0][u] = p; rep(i, 1, 17) par[i][u] = par[i - 1][par[i - 1][u]]; for (int v : adj[u]) if (v != p) dfs(v, u); ed[u] = ++lan; } bool is_par(int u, int v) { return (st[u] <= st[v] && ed[u] >= ed[v]); } int lca(int u, int v) { if (is_par(u, v)) return u; if (is_par(v, u)) return v; rev(i, 17, 0) if (!is_par(par[i][u], v)) u = par[i][u]; return par[0][u]; } bool add(int u) { if (u == head) return 1; if (head == 0) { head = u; return 1; } if (l == 0 && r == 0) { if (is_par(u, head)) { l = head; head = u; return 1; } else if (is_par(head, u)) { l = u; return 1; } else { l = head; r = u; head = lca(l, r); return 1; } } else if (l != 0 && r == 0) { if (is_par(u, head)) { head = u; return 1; } else if (!is_par(head, u)) { r = u; head = lca(u, head); return 1; } else { if (is_par(u, l)) return 1; if (is_par(l, u)) { l = u; return 1; } if (lca(u, l) == head) { r = u; return 1; } return 0; } } else { if (is_par(u, head)) return 0; else if (!is_par(head, u)) return 0; else { if (is_par(u, l)) return 1; if (is_par(l, u)) { l = u; return 1; } if (is_par(u, r)) return 1; if (is_par(r, u)) { r = u; return 1; } return 0; } } } int main() { //freopen("D:\\test.txt", "r", stdin); //freopen("D:\\test2.txt", "w", stdout); cin >> n; rep(i, 1, n - 1) { int u, v; cin >> u >> v; adj[u].push_back(v); adj[v].push_back(u); } dfs(1, 0); st[0] = -1; ed[0] = ++lan; int q; cin >> q; rep(i, 1, q) { head = l = r = 0; int k; cin >> k; bool flag = 1; rep(i, 1, k) { int u; cin >> u; if (!flag) continue; flag = add(u); } if (flag) cout << "YES\n"; else cout << "NO\n"; } } ``` ::: ngoài lề : sol trên cf nghe đơn giản phết, tự thấy mình non=)))))