/* Author : Mychecksdead */
#include<bits/stdc++.h>
using namespace std;
#define ll long long int
#define MOD (1000000000+7)
#define MOD1 (998244353)
#define pb push_back
#define all(x) x.begin(), x.end()
#define en cout << '\n'
#define ff first
#define ss second
#define pii pair<int,int>
#define vi vector<int>
const int N = 120100*4, M = 1e5+10, K = 20, MX = 30;
int n, m, s[N], heavy[N], tin[N], tout[N], timer, par[N], up[N][K], dep[N];
vi g[N];
array<int, 2> a[N];
vector<set<int>> A, A2, B, B2;
bool dead;
vi vis;
bool is_ancestor(int u, int v){
return tin[u] <= tin[v] && tout[v] <= tout[u];
}
int _lca(int u, int v){
if(is_ancestor(u, v)) return u;
if(is_ancestor(v, u)) return v;
for(int j = K-1; j >= 0; --j){
if(!is_ancestor(up[u][j], v)) u = up[u][j];
}
return up[u][0];
}
void pre(int v, int p){
s[v] = 1;
for(int &u: g[v]){
if(u != p){
pre(u, v);
s[v] += s[u];
if(g[v][0] == p || s[g[v][0]] < s[u]) swap(u, g[v][0]);
}
}
}
void dfs(int v, int p){
tin[v] = timer++;
up[v][0] = p;
par[v] = p;
dep[v] = dep[p] + 1;
for(int u: g[v]){
if(u==p) continue;
if(u == g[v][0]) heavy[u] = heavy[v];
else heavy[u] = u;
dfs(u, v);
}
tout[v] = timer - 1;
}
// tp 1
void upd(int l, int r, int ql, int qr, int k, int val, vector<set<int>> &T){
if(ql > r || l > qr) return;
if(ql <= l && r <= qr){
if(val > 0) T[k].insert(val);
else T[k].erase(-val);
return;
}
int mid = l+r>>1;
upd(l, mid, ql, qr, k<<1, val, T);
upd(mid+1, r, ql, qr, k<<1|1, val, T);
}
// tp 2
void upd2(int l, int r, int p, int k, int val, vector<set<int>> &T){
if(val > 0) T[k].insert(val);
else T[k].erase(-val);
if(l == r){
return;
}
int mid = l+r>>1;
if(p <= mid) upd2(l, mid, p, k<<1, val, T);
else upd2(mid+1, r, p, k<<1|1, val, T);
}
void put(int u, int v, int val, vector<set<int>> &T){
// do some hld
// put val into path u...v
int lca = _lca(u, v);
while(u != lca){
if(dep[heavy[u]] > dep[lca]){
upd(1, n, tin[heavy[u]], tin[u], 1, val, T);
u = par[heavy[u]];
}else{
upd(1, n, tin[lca], tin[u], 1, val, T);
u = lca;
}
}
u = v;
while(u != lca){
if(dep[heavy[u]] > dep[lca]){
upd(1, n, tin[heavy[u]], tin[u], 1, val, T);
u = par[heavy[u]];
}else{
upd(1, n, tin[lca] + 1, tin[u], 1, val, T); // avoid putting multiple at some point.
u = lca;
}
}
}
int query(int l, int r, int ql, int qr, int k, vector<set<int>> &T, int other){ // check whether anyone on
if(ql > r || l > qr) return 0;
if(ql <= l && r <= qr) return T[k].empty() ? 0 : ((*T[k].begin()) == other ? (T[k].size() == 1 ? 0 : (*next(T[k].begin()))) : (*T[k].begin()));
int mid = l+r>>1;
return max(query(l, mid, ql, qr, k<<1, T, other), query(mid+1, r, ql, qr, k<<1|1, T, other));
}
int query2(int l, int r, int p, int k, vector<set<int>> &T, int other){ // check whether anyone on
if(T[k].size() && (T[k].size() > 1 || (*T[k].begin()) != other)){
return (*T[k].begin()) == other ? (*next(T[k].begin())) : (*T[k].begin());
}
if(l == r) return T[k].empty() ? 0 : ((*T[k].begin()) == other ? (T[k].size() == 1 ? 0 : (*next(T[k].begin()))) : (*T[k].begin()));
int mid = l+r>>1;
if(p <= mid) return query2(l, mid, p, k<<1, T, other);
return query2(mid+1, r, p, k<<1|1, T, other);
}
int query_path(int u, int v, vector<set<int>> &T, int other){
int lca = _lca(u, v);
// cerr << u << ' ' << v << ' ' << lca << '\n';
while(u != lca){
if(dep[heavy[u]] > dep[lca]){
int x = query(1, n, tin[heavy[u]], tin[u], 1, T, other);
if(x) return x;
u = par[heavy[u]];
}else{
int x = query(1, n, tin[lca], tin[u], 1, T, other);
if(x) return x;
u = lca;
}
}
u = v;
while(u != lca){
if(dep[heavy[u]] > dep[lca]){
int x = query(1, n, tin[heavy[u]], tin[u], 1, T, other);
if(x) return x;
u = par[heavy[u]];
}else{
int x = query(1, n, tin[lca] + 1, tin[u], 1, T, other);
if(x) return x;
u = lca;
}
}
return 0;
}
void DFS(int v){
// put v into the stack
vis[v] = 1;
put(a[v][0], a[v][1], -v, A);
put(a[v][0], a[v][1], v, A2);
upd2(1, n, tin[a[v][0]], 1, -v, B);
upd2(1, n, tin[a[v][0]], 1, v, B2);
// type 1 edges
// check loop
int b = query_path(a[v][0], a[v][1], B2, v); // this part will be fixed
if(b > 0){
// cerr << " here\n";
dead = 1; // there is someone with vis[v] = 1.
return;
}
int u = query_path(a[v][0], a[v][1], B, v);
while(u){
DFS(u);
u = query_path(a[v][0], a[v][1], B, v);
}
// type 2 edges
b = query2(1, n, tin[a[v][1]], 1, A2, v);
if(b > 0){
dead = 1; // cycle
return;
}
u = query2(1, n, tin[a[v][1]], 1, A, v);
while(u){
DFS(u);
u = query2(1, n, tin[a[v][1]], 1, A, v);
}
// pop v
vis[v] = 2;
put(a[v][0], a[v][1], -v, A2);
upd2(1, n, tin[a[v][0]], 1, -v, B2);
}
void solve(){
cin >> n;
for(int i = 1; i <= n; ++i){
g[i].clear();
}
for(int i = 1; i < n; ++i){
int u, v; cin >> u >> v;
g[u].pb(v);
g[v].pb(u);
}
cin >> m;
vis.clear();
vis.resize(m + 1, 0);
A.clear(); A.resize(4*n);
A2.clear(); A2.resize(4*n);
B2.clear(); B2.resize(4*n);
B.clear(); B.resize(4*n);
for(int i = 1; i <= m; ++i){
cin >> a[i][0] >> a[i][1];
}
pre(1, 1);
dep[1] = 0;
timer = 1;
heavy[1] = 1;
dfs(1, 1);
for(int j = 1; j < K; ++j){
for(int i = 1; i <= n; ++i){
up[i][j] = up[up[i][j - 1]][j - 1];
}
}
for(int i = 1; i <= m; ++i){
put(a[i][0], a[i][1], i, A); // range put (B_j -> i edge)
}
for(int i = 1; i <= m; ++i){
upd2(1, n, tin[a[i][0]], 1, i, B); // point put (i -> A_j edge)
}
dead = false;
for(int i = 1; i <= m; ++i){
if(vis[i] == 0 && !dead){
DFS(i);
}
}
cout << (dead ? "No" : "Yes");
}
int main(){
cin.tie(0); ios::sync_with_stdio(0);
int tt = 1, aa;
// freopen("in.txt", "r", stdin);
// freopen("out.txt", "w", stdout);
cin >> tt;
while(tt--){
solve();
en;
}
cerr<<"time taken : "<<(float)clock()/CLOCKS_PER_SEC<<" seconds\n";
return 0;
}
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |