# 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=)))))