제출 #1249129

#제출 시각아이디문제언어결과실행 시간메모리
1249129rayan_bdValley (BOI19_valley)C++20
100 / 100
84 ms23736 KiB
#include <bits/stdc++.h>
using namespace std;

#define ll long long

const int mxN = 1e5 + 100;
const ll INF = 1e18;

vector<pair<int, int>> adj[mxN];
int par[mxN], depth[mxN], head[mxN], heavy[mxN], sz[mxN], tin[mxN], tout[mxN], st[mxN], t = -1, t2 = -1;
ll dp[mxN], path_sum[mxN], seg[mxN * 4], lt[mxN];

struct seg_tree {
	void build(int node, int start, int end) {
		if (start == end) {
			seg[node] = lt[start];
			return;
		}
		int mid = (start + end) / 2;
		build(node * 2 + 1, start, mid);
		build(node * 2 + 2, mid + 1, end);
		seg[node] = min(seg[node * 2 + 1], seg[node * 2 + 2]);
	}

	ll query(int node, int start, int end, int l, int r) {
		if (start > r || end < l) return INF;
		if (start >= l && end <= r) return seg[node];
		int mid = (start + end) / 2;
		return min(query(node * 2 + 1, start, mid, l, r),
		           query(node * 2 + 2, mid + 1, end, l, r));
	}
} tr;

struct hld {
	void dfs(int u = 1, int p = 0) {
		depth[u] = depth[p] + 1;
		par[u] = p;
		sz[u] = 1;
		tin[u] = ++t2;
		for (auto it : adj[u]) {
			int v = it.first, w = it.second;
			if (v != p) {
				path_sum[v] = path_sum[u] + w;
				dfs(v, u);
				dp[u] = min(dp[u], dp[v] + w);
				sz[u] += sz[v];
				if (sz[heavy[u]] < sz[v]) {
					heavy[u] = v;
				}
			}
		}
		tout[u] = ++t2;
	}

	void dfs_hld(int u = 1, int chain = 1, int p = 0) {
		head[u] = chain;
		lt[++t] = dp[u] - path_sum[u];
		st[u] = t;
		if (heavy[u]) {
			dfs_hld(heavy[u], chain, u);
		}
		for (auto it : adj[u]) {
			int v = it.first;
			if (v != p && heavy[u] != v) {
				dfs_hld(v, v, u);
			}
		}
	}

	bool subtree(int u, int v) {
		return tin[v] >= tin[u] && tout[v] <= tout[u];
	}

	ll query(int u, int v) {
		ll ans = INF;
		while (head[u] != head[v]) {
			if (depth[head[u]] < depth[head[v]])
				swap(u, v);
			ans = min(ans, tr.query(0, 0, t, st[head[u]], st[u]));
			u = par[head[u]];
		}
		if (st[u] > st[v]) swap(u, v);
		ans = min(ans, tr.query(0, 0, t, st[u], st[v]));
		return ans;
	}

} hld;

int main() {
	ios_base::sync_with_stdio(0);
	cin.tie(nullptr); cout.tie(nullptr);

	int n, s, q, e;
	cin >> n >> s >> q >> e;

	vector<pair<int, int>> edge;

	for (int i = 0; i < n - 1; ++i) {
		int u, v, w;
		cin >> u >> v >> w;
		adj[u].push_back({v, w});
		adj[v].push_back({u, w});
		edge.emplace_back(u, v);
	}

	for (int i = 1; i <= n; ++i) {
		dp[i] = INF;
	}

	for (int i = 0; i < s; ++i) {
		int u;
		cin >> u;
		dp[u] = 0;
	}

	hld.dfs(e, 0);
	hld.dfs_hld(e, e, 0);
	tr.build(0, 0, t);

	while (q--) {
		int edge_id, u;
		cin >> edge_id >> u;
		--edge_id;
		int u1 = edge[edge_id].first;
		int u2 = edge[edge_id].second;

		if (hld.subtree(u1, u) && hld.subtree(u2, u) && u != e) {
			if (depth[u1] < depth[u2]) swap(u1, u2);
			ll answer = hld.query(u, u1) + path_sum[u];
			if (answer >= INF) {
				cout << "oo\n";
			} else {
				cout << answer << "\n";
			}
		} else {
			cout << "escaped\n";
		}
	}

	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...