제출 #1117187

#제출 시각아이디문제언어결과실행 시간메모리
1117187xnqsValley (BOI19_valley)C++17
100 / 100
98 ms39056 KiB
#include <iostream> #include <fstream> #include <vector> #include <queue> #include <utility> #include <algorithm> int gs, sh, q, dest; std::vector<std::vector<std::pair<int,int>>> adj_list; std::vector<std::tuple<int,int,int>> edges; bool is_shop[100005]; std::vector<int> shops; int tin[100005]; int tout[100005]; int depth[100005]; int64_t dist[100005]; int64_t best_root_path[100005]; int up[17][100005]; int64_t dp[17][100005]; void dfs1(int k, int p, int& timer) { tin[k] = tout[k] = ++timer; depth[k] = depth[p]+1; up[0][k] = p; best_root_path[k] = ((is_shop[k]) ? dist[k] : 0x3f3f3f3f3f3f3f3f); for (const auto& [i, w] : adj_list[k]) { if (i!=p) { dist[i] = dist[k]+w; dfs1(i,k,timer); best_root_path[k] = std::min(best_root_path[k], best_root_path[i]); tout[k] = ++timer; } } } void preprocess_binary_lifting() { for (int l = 1; l < 17; l++) { for (int i = 1; i <= gs; i++) { up[l][i] = up[l-1][up[l-1][i]]; dp[l][i] = std::min(dp[l-1][i], dp[l-1][up[l-1][i]]); } } } int64_t path_min(int a, int b) { if (depth[a]>depth[b]) { std::swap(a,b); } int64_t ret = 0x3f3f3f3f3f3f3f3f; int diff = depth[b]-depth[a]; while (diff) { int l = 31-__builtin_clz(diff); ret = std::min(ret, dp[l][b]); b = up[l][b]; diff ^= (1<<l); } for (int l = 16; a!=b;) { while (l-1>=0&&up[l][a]==up[l][b]) { --l; } ret = std::min(ret, dp[l][a]); ret = std::min(ret, dp[l][b]); a = up[l][a]; b = up[l][b]; } return ret; } inline bool inside(int a, int b) { return tin[a] <= tin[b] && tout[b] <= tout[a]; } int main() { std::ios_base::sync_with_stdio(false); std::cin.tie(NULL); std::cout.tie(NULL); std::cin >> gs >> sh >> q >> dest; adj_list.resize(gs+1); for (int i = 0, a, b, c; i < gs-1; i++) { std::cin >> a >> b >> c; adj_list[a].emplace_back(b,c); adj_list[b].emplace_back(a,c); edges.emplace_back(a,b,c); } shops.reserve(sh); for (int i = 0, tmp; i < sh; i++) { std::cin >> tmp; is_shop[tmp] = 1; shops.emplace_back(tmp); } { int timer = 0; dfs1(dest,0,timer); } for (int i = 1; i <= gs; i++) { dp[0][i] = best_root_path[i] - 2*dist[i]; } preprocess_binary_lifting(); for (auto& [a, b, c] : edges) { if (depth[a]>depth[b]) { std::swap(a,b); } } while (q--) { int edge_idx, node; std::cin >> edge_idx >> node; --edge_idx; if (!(inside(std::get<1>(edges[edge_idx]),dest)^inside(std::get<1>(edges[edge_idx]),node))) { std::cout << "escaped\n"; } else { if (best_root_path[std::get<1>(edges[edge_idx])]==0x3f3f3f3f3f3f3f3f) { std::cout << "oo\n"; } else { int64_t ans = dist[node] + path_min(std::get<0>(edges[edge_idx]),node); std::cout << ans << "\n"; } } } }
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...