#include <bits/stdc++.h>
using namespace std;
#define dbg(x) "[" #x " = " << (x) << "]"
bool cycle_detection(vector<vector<int>>& adj){
int N = (int)adj.size();
vector<int> vis(N);
// cout << "edges ;;;;;\n";
// for(int i = 0; i < N; ++i){
// for(int j : adj[i]){
// cout << i << " " << j << '\n';
// }
// }
// cout << '\n';
function<bool(int)> dfs = [&](int u){
vis[u] = 1;
for(auto v : adj[u]){
if(!vis[v]){
if(dfs(v)) return true;
} else if(vis[v] == 1){
return true;
}
}
vis[u] = 2;
return false;
};
for(int i = 0; i < N; ++i){
if(!vis[i] && dfs(i)) return true;
}
return false;
}
struct path_decomposition_tree{
int N, timerHLD, num;
vector<int> par, depth, sz, tin, tout, head, idx, ln, rn;
vector<vector<int>> adj;
vector<pair<int, int>> edges;
path_decomposition_tree(int N) :
timerHLD(0), num(0), N(N), depth(N), sz(N), tin(N, -1), tout(N, -1), par(N), head(N), adj(N), edges(), idx(N),
ln(4 * N, -1), rn(4 * N, -1) {}
void add_edge(int u, int v){
adj[u].emplace_back(v);
adj[v].emplace_back(u);
}
void dfs_sz(int u){
sz[u] = 1;
for(auto& v : adj[u]){
adj[v].erase(find(adj[v].begin(), adj[v].end(), u));
depth[v] = depth[u] + 1;
par[v] = u;
dfs_sz(v);
if(sz[adj[u][0]] < sz[v]) swap(adj[u][0], v);
sz[u] += sz[v];
}
}
void dfs_hld(int u, int hd){
head[u] = hd;
tin[u] = timerHLD++;
for(auto v : adj[u]){
if(v == adj[u][0]) dfs_hld(v, hd);
else dfs_hld(v, v);
}
tout[u] = timerHLD - 1;
}
int build(int l, int r){
if(l == r){
idx[l] = num++;
return idx[l];
} else{
int mid = l + r >> 1, cur = num++;
ln[cur] = build(l, mid);
rn[cur] = build(mid + 1, r);
edges.emplace_back(cur, ln[cur]);
edges.emplace_back(cur, rn[cur]);
return cur;
}
}
void preprocess(int rt){
dfs_sz(rt);
dfs_hld(rt, rt);
assert(timerHLD == N);
build(0, N - 1);
}
int auxiliary_nodes(){ return num; }
bool in_subtree(int u, int v){ return tin[u] <= tin[v] && tout[v] <= tout[u]; }
void query_auxiliary_nodes(int cur, int l, int r, int u, int v, vector<int>& ans){
if(u <= l && r <= v){
ans.emplace_back(cur);
} else{
int mid = l + r >> 1;
if(u <= mid) query_auxiliary_nodes(ln[cur], l, mid, u, v, ans);
if(mid < v) query_auxiliary_nodes(rn[cur], mid + 1, r, u, v, ans);
}
}
vector<int> query(int u, int v){ //ignore u, v
vector<int> cur;
if(tin[u] > tin[v]) swap(u, v);
if(in_subtree(u, v)){
v = par[v];
while(head[u] != head[v]){
if(depth[head[u]] < depth[head[v]]) swap(u, v);
query_auxiliary_nodes(0, 0, N - 1, tin[head[u]], tin[u], cur);
u = par[head[u]];
}
if(tin[u] < tin[v]) query_auxiliary_nodes(0, 0, N - 1, tin[u] + 1, tin[v], cur);
return cur;
} else{
u = par[u];
v = par[v];
}
while(head[u] != head[v]){
if(depth[head[u]] < depth[head[v]]) swap(u, v);
query_auxiliary_nodes(0, 0, N - 1, tin[head[u]], tin[u], cur);
u = par[head[u]];
}
if(tin[u] > tin[v]) swap(u, v);
query_auxiliary_nodes(0, 0, N - 1, tin[u], tin[v], cur);
return cur;
}
};
void testcase(){
int N;
cin >> N;
path_decomposition_tree tr(N);
for(int i = 1; i < N; ++i){
int u, v;
cin >> u >> v;
--u, --v;
tr.add_edge(u, v);
}
int M;
cin >> M;
tr.preprocess(0);
int offset = tr.auxiliary_nodes();
int nodes = 2 * offset + M;
vector<vector<int>> G(nodes);
for(auto [u, v] : tr.edges){
G[u].emplace_back(v); //for T
G[v + offset].emplace_back(u + offset); //for S
}
for(int i = 0; i < M; ++i){
int s, t;
cin >> s >> t;
--s, --t;
int loc = 2 * offset + i;
vector<int> compress_nodes = tr.query(s, t); //auxiliary nodes without s, t
for(auto it : compress_nodes){
G[loc].emplace_back(it);
G[it + offset].emplace_back(loc);
}
int pS = tr.idx[s];
G[loc].emplace_back(pS + offset);
G[loc].emplace_back(pS);
int pT = tr.idx[t];
G[pT].emplace_back(loc);
G[pT + offset].emplace_back(loc);
}
cout << (cycle_detection(G) ? "No\n" : "Yes\n");
}
int main(){
ios_base::sync_with_stdio(0);
cin.tie(0);
int T;
cin >> T;
while(T--) testcase();
return 0;
}
Compilation message
jail.cpp: In constructor 'path_decomposition_tree::path_decomposition_tree(int)':
jail.cpp:39:22: warning: 'path_decomposition_tree::num' will be initialized after [-Wreorder]
39 | int N, timerHLD, num;
| ^~~
jail.cpp:39:9: warning: 'int path_decomposition_tree::N' [-Wreorder]
39 | int N, timerHLD, num;
| ^
jail.cpp:44:5: warning: when initialized here [-Wreorder]
44 | path_decomposition_tree(int N) :
| ^~~~~~~~~~~~~~~~~~~~~~~
jail.cpp:40:38: warning: 'path_decomposition_tree::tout' will be initialized after [-Wreorder]
40 | vector<int> par, depth, sz, tin, tout, head, idx, ln, rn;
| ^~~~
jail.cpp:40:17: warning: 'std::vector<int> path_decomposition_tree::par' [-Wreorder]
40 | vector<int> par, depth, sz, tin, tout, head, idx, ln, rn;
| ^~~
jail.cpp:44:5: warning: when initialized here [-Wreorder]
44 | path_decomposition_tree(int N) :
| ^~~~~~~~~~~~~~~~~~~~~~~
jail.cpp:42:28: warning: 'path_decomposition_tree::edges' will be initialized after [-Wreorder]
42 | vector<pair<int, int>> edges;
| ^~~~~
jail.cpp:40:50: warning: 'std::vector<int> path_decomposition_tree::idx' [-Wreorder]
40 | vector<int> par, depth, sz, tin, tout, head, idx, ln, rn;
| ^~~
jail.cpp:44:5: warning: when initialized here [-Wreorder]
44 | path_decomposition_tree(int N) :
| ^~~~~~~~~~~~~~~~~~~~~~~
jail.cpp: In member function 'int path_decomposition_tree::build(int, int)':
jail.cpp:80:25: warning: suggest parentheses around '+' inside '>>' [-Wparentheses]
80 | int mid = l + r >> 1, cur = num++;
| ~~^~~
jail.cpp: In member function 'void path_decomposition_tree::query_auxiliary_nodes(int, int, int, int, int, std::vector<int>&)':
jail.cpp:104:25: warning: suggest parentheses around '+' inside '>>' [-Wparentheses]
104 | int mid = l + r >> 1;
| ~~^~~
jail.cpp: In function 'void testcase()':
jail.cpp:164:14: warning: structured bindings only available with '-std=c++17' or '-std=gnu++17'
164 | for(auto [u, v] : tr.edges){
| ^
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Correct |
1 ms |
336 KB |
Output is correct |
2 |
Correct |
1 ms |
336 KB |
Output is correct |
3 |
Correct |
1 ms |
336 KB |
Output is correct |
4 |
Correct |
20 ms |
848 KB |
Output is correct |
5 |
Correct |
42 ms |
1104 KB |
Output is correct |
6 |
Correct |
3 ms |
592 KB |
Output is correct |
7 |
Correct |
3 ms |
592 KB |
Output is correct |
8 |
Correct |
5 ms |
592 KB |
Output is correct |
9 |
Correct |
56 ms |
5844 KB |
Output is correct |
10 |
Correct |
124 ms |
85188 KB |
Output is correct |
11 |
Correct |
10 ms |
628 KB |
Output is correct |
12 |
Correct |
59 ms |
1432 KB |
Output is correct |
13 |
Correct |
164 ms |
92344 KB |
Output is correct |
14 |
Correct |
157 ms |
92600 KB |
Output is correct |
15 |
Correct |
300 ms |
97380 KB |
Output is correct |
16 |
Correct |
399 ms |
114616 KB |
Output is correct |
17 |
Correct |
181 ms |
101084 KB |
Output is correct |
18 |
Correct |
145 ms |
97208 KB |
Output is correct |
19 |
Correct |
190 ms |
98808 KB |
Output is correct |
20 |
Correct |
181 ms |
98764 KB |
Output is correct |
21 |
Correct |
199 ms |
99768 KB |
Output is correct |
22 |
Correct |
131 ms |
91320 KB |
Output is correct |
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Correct |
1 ms |
336 KB |
Output is correct |
2 |
Correct |
1 ms |
592 KB |
Output is correct |
3 |
Correct |
2 ms |
592 KB |
Output is correct |
4 |
Incorrect |
3 ms |
592 KB |
Output isn't correct |
5 |
Halted |
0 ms |
0 KB |
- |
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Correct |
1 ms |
336 KB |
Output is correct |
2 |
Correct |
1 ms |
592 KB |
Output is correct |
3 |
Correct |
2 ms |
592 KB |
Output is correct |
4 |
Incorrect |
3 ms |
592 KB |
Output isn't correct |
5 |
Halted |
0 ms |
0 KB |
- |
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Correct |
1 ms |
336 KB |
Output is correct |
2 |
Correct |
1 ms |
592 KB |
Output is correct |
3 |
Correct |
2 ms |
592 KB |
Output is correct |
4 |
Incorrect |
3 ms |
592 KB |
Output isn't correct |
5 |
Halted |
0 ms |
0 KB |
- |
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Correct |
1 ms |
336 KB |
Output is correct |
2 |
Correct |
1 ms |
592 KB |
Output is correct |
3 |
Correct |
2 ms |
592 KB |
Output is correct |
4 |
Incorrect |
3 ms |
592 KB |
Output isn't correct |
5 |
Halted |
0 ms |
0 KB |
- |
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Correct |
1 ms |
336 KB |
Output is correct |
2 |
Correct |
1 ms |
336 KB |
Output is correct |
3 |
Correct |
1 ms |
508 KB |
Output is correct |
4 |
Correct |
1 ms |
336 KB |
Output is correct |
5 |
Correct |
11 ms |
592 KB |
Output is correct |
6 |
Correct |
2 ms |
504 KB |
Output is correct |
7 |
Incorrect |
3 ms |
468 KB |
Output isn't correct |
8 |
Halted |
0 ms |
0 KB |
- |
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Correct |
1 ms |
336 KB |
Output is correct |
2 |
Correct |
1 ms |
336 KB |
Output is correct |
3 |
Correct |
1 ms |
336 KB |
Output is correct |
4 |
Correct |
20 ms |
848 KB |
Output is correct |
5 |
Correct |
42 ms |
1104 KB |
Output is correct |
6 |
Correct |
3 ms |
592 KB |
Output is correct |
7 |
Correct |
3 ms |
592 KB |
Output is correct |
8 |
Correct |
5 ms |
592 KB |
Output is correct |
9 |
Correct |
56 ms |
5844 KB |
Output is correct |
10 |
Correct |
124 ms |
85188 KB |
Output is correct |
11 |
Correct |
10 ms |
628 KB |
Output is correct |
12 |
Correct |
59 ms |
1432 KB |
Output is correct |
13 |
Correct |
164 ms |
92344 KB |
Output is correct |
14 |
Correct |
157 ms |
92600 KB |
Output is correct |
15 |
Correct |
300 ms |
97380 KB |
Output is correct |
16 |
Correct |
399 ms |
114616 KB |
Output is correct |
17 |
Correct |
181 ms |
101084 KB |
Output is correct |
18 |
Correct |
145 ms |
97208 KB |
Output is correct |
19 |
Correct |
190 ms |
98808 KB |
Output is correct |
20 |
Correct |
181 ms |
98764 KB |
Output is correct |
21 |
Correct |
199 ms |
99768 KB |
Output is correct |
22 |
Correct |
131 ms |
91320 KB |
Output is correct |
23 |
Correct |
1 ms |
336 KB |
Output is correct |
24 |
Correct |
1 ms |
592 KB |
Output is correct |
25 |
Correct |
2 ms |
592 KB |
Output is correct |
26 |
Incorrect |
3 ms |
592 KB |
Output isn't correct |
27 |
Halted |
0 ms |
0 KB |
- |