Submission #941651

#TimeUsernameProblemLanguageResultExecution timeMemory
941651alextodoranJail (JOI22_jail)C++17
100 / 100
849 ms300576 KiB
/** _ _ __ _ _ _ _ _ _ |a ||t ||o d | |o | | __ _| | _ | __| _ | | __ |/_ | __ /__\ / _\| **/ #include <bits/stdc++.h> using namespace std; typedef long long ll; const int N_MAX = 120000; const int M_MAX = N_MAX; const int LOG_N = 17; const int V_MAX = M_MAX + N_MAX * LOG_N * 2; int Q; int N; vector <int> adj[N_MAX + 2]; int M; int start[M_MAX + 2], finish[M_MAX + 2]; int parent[N_MAX + 2]; int depth[N_MAX + 2]; void dfs (int u) { for (int v : adj[u]) { if (v != parent[u]) { parent[v] = u; depth[v] = depth[u] + 1; dfs(v); } } } int start_id[N_MAX + 2], finish_id[N_MAX + 2]; int V; vector <int> out[V_MAX + 2]; int deg[V_MAX + 2]; void add_edge (int u, int v) { out[u].push_back(v); deg[v]++; } int anc[N_MAX + 2][LOG_N]; int seg_out[N_MAX + 2][LOG_N]; int seg_in[N_MAX + 2][LOG_N]; void build () { for (int u = 1; u <= N; u++) { anc[u][0] = parent[u]; } for (int k = 1; k < LOG_N; k++) { for (int u = 1; u <= N; u++) { anc[u][k] = anc[anc[u][k - 1]][k - 1]; } } V = M; for (int u = 1; u <= N; u++) { seg_out[u][0] = ++V; seg_in[u][0] = ++V; if (finish_id[u] != 0) { add_edge(seg_out[u][0], finish_id[u]); } if (start_id[u] != 0) { add_edge(start_id[u], seg_in[u][0]); } } for (int k = 1; k < LOG_N; k++) { for (int u = 1; u <= N; u++) { seg_out[u][k] = ++V; seg_in[u][k] = ++V; add_edge(seg_out[u][k], seg_out[u][k - 1]); add_edge(seg_in[u][k - 1], seg_in[u][k]); if (anc[u][k - 1] != 0) { add_edge(seg_out[u][k], seg_out[anc[u][k - 1]][k - 1]); add_edge(seg_in[anc[u][k - 1]][k - 1], seg_in[u][k]); } } } } int ancestor (int u, int len) { for (int k = 0; k < LOG_N; k++) { if ((len >> k) & 1) { u = anc[u][k]; } } return u; } int lca (int u, int v) { if (depth[u] > depth[v]) { u = ancestor(u, depth[u] - depth[v]); } if (depth[v] > depth[u]) { v = ancestor(v, depth[v] - depth[u]); } if (u == v) { return u; } for (int k = LOG_N - 1; k >= 0; k--) { if (anc[u][k] != anc[v][k]) { u = anc[u][k]; v = anc[v][k]; } } return parent[u]; } void add_path (int i, int u, int v) { int len = depth[u] - depth[v]; for (int k = 0; k < LOG_N; k++) { if ((len >> k) & 1) { add_edge(i, seg_out[u][k]); add_edge(seg_in[u][k], i); u = anc[u][k]; } } } void clean () { for (int u = 1; u <= N; u++) { adj[u].clear(); parent[u] = 0; depth[u] = 0; start_id[u] = 0; finish_id[u] = 0; } for (int u = 1; u <= V; u++) { out[u].clear(); deg[u] = 0; } } int main () { ios_base::sync_with_stdio(false); cin.tie(0); cin >> Q; while (Q--) { cin >> N; for (int i = 1; i <= N - 1; i++) { int u, v; cin >> u >> v; adj[u].push_back(v); adj[v].push_back(u); } dfs(1); cin >> M; for (int i = 1; i <= M; i++) { cin >> start[i] >> finish[i]; start_id[start[i]] = i; finish_id[finish[i]] = i; } build(); for (int i = 1; i <= M; i++) { int u = start[i], v = finish[i]; int x = lca(u, v); if (u != x) { add_path(i, parent[u], x); } if (v != x) { add_path(i, parent[v], x); } if (finish_id[u] != 0) { add_edge(i, finish_id[u]); } if (start_id[v] != 0) { add_edge(start_id[v], i); } if (u != x && v != x) { if (finish_id[x] != 0) { add_edge(i, finish_id[x]); } if (start_id[x] != 0) { add_edge(start_id[x], i); } } } queue <int> q; for (int u = 1; u <= V; u++) { if (deg[u] == 0) { q.push(u); } } while (q.empty() == false) { int u = q.front(); q.pop(); for (int v : out[u]) { if (--deg[v] == 0) { q.push(v); } } } bool ok = true; for (int u = 1; u <= V; u++) { if (deg[u] > 0) { ok = false; break; } } cout << (ok == true ? "Yes" : "No") << "\n"; clean(); } return 0; }
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...