이 제출은 이전 버전의 oj.uz에서 채점하였습니다. 현재는 제출 당시와는 다른 서버에서 채점을 하기 때문에, 다시 제출하면 결과가 달라질 수도 있습니다.
#include <iostream>
#include <vector>
#include <algorithm>
#include <cmath>
#include <unordered_set>
#include <cstdlib>
#include <cstring>
#include <string>
#include <set>
using namespace std;
const int N = 1e5 + 10;
bool A[N];
int dist[N];
int par[N];
int rankk[N];
vector <vector<pair<int, int>>> G;
struct esim {
	int a;
	int b;
	int w;
};
bool cmp(esim x, esim y) {
	if (x.w != y.w) return x.w > y.w;
	if (x.a != y.a) return x.a < y.a;
	return x.b < y.b;
}
void make_set(int v) {
	par[v] = v;
	rankk[v] = 0;
	return;
}
int find_set(int a) {
	if (par[a] == a) return a;
	return par[a] = find_set(par[a]);
}
bool union_sets(int a, int b) {
	a = find_set(a);
	b = find_set(b);
	if (a == b) return false;
	if (rankk[a] < rankk[b]) {
		swap(a, b);
	}
	par[b] = a;
	if (rankk[a] == rankk[b]) ++rankk[a];
	return true;
}
int dp[N][20];
int up[N][20];
int tin[N];
int tout[N];
int h[N];
int timer = 0;
void dfs(int v, int p, int prev) {
	tin[v] = ++timer;
	dp[v][0] = prev;
	up[v][0] = p;
	for (int i = 1; i < 20; i++) {
		up[v][i] = up[up[v][i - 1]][i - 1];
		dp[v][i] = min(dp[v][i - 1], dp[up[v][i - 1]][i - 1]);
	}
	for (auto it : G[v]) {
		if (it.first == p) continue;
		h[it.first] = h[v] + 1;
		dfs(it.first, v, it.second);
	}
	tout[v] = ++timer;
}
bool is_par(int a, int b) {
	if (tin[a] <= tin[b] && tout[a] >= tout[b]) return true;
	return false;
}
int lca(int a, int b) {
	if (is_par(a, b)) return a;
	for (int i = 19; i >= 0; i--) {
		if (!is_par(up[a][i], b)) {
			a = up[a][i];
		}
	}
	return up[a][0];
}
int val(int a, int b) {
	int u = lca(a, b);
	int k = h[a] - h[u];
	int mn = 1e9 + 10;
	for (int i = 19; i >= 0; i--) {
		if (k & (1 << i)) {
			mn = min(mn, dp[a][i]);
			a = up[a][i];
		}
	}
	k = h[b] - h[u];
	for (int i = 19; i >= 0; i--) {
		if (k & (1 << i)) {
			mn = min(mn, dp[b][i]);
			b = up[b][i];
		}
	}
	return mn;
}
int main() {
	ios_base::sync_with_stdio(false); cin.tie(0);
	int n, m;
	cin >> n >> m;
	G.resize(n + 1);
	for (int i = 1; i <= n; i++) {
		dist[i] = 1e9 + 10;
	}
	vector <pair<int, int>> edges;
	for (int i = 1; i <= m; i++) {
		int a, b, d;
		cin >> a >> b >> d;
		edges.push_back({ a, b });
		G[a].push_back({ b, d });
		G[b].push_back({ a, d });
	}
	int k;
	cin >> k;
	set <pair<int, int>> ms;
	for (int i = 1; i <= k; i++) {
		int x;
		cin >> x;
		A[x] = true;
		ms.insert({ 0, x });
		dist[x] = 0;
	}
	while (!ms.empty()) {
		int v = ms.begin()->second; ms.erase(ms.begin());
		for (auto it : G[v]) {
			if (dist[v] + it.second < dist[it.first]) {
				auto q = ms.find(make_pair(dist[it.first], it.first));
				if (q != ms.end()) ms.erase(q);
				dist[it.first] = dist[v] + it.second;
				ms.insert({ dist[it.first], it.first });
			}
		}
	}
	G.clear();
	G.resize(n + 1);
	for (int i = 1; i <= n; i++) {
		make_set(i);
	}
	vector <esim> v;
	for (auto it : edges) {
		v.push_back({ it.first, it.second, min(dist[it.first], dist[it.second]) });
	}
	int q;
	cin >> q;
	sort(v.begin(), v.end(), cmp);
	for (auto it : v) {
		if (union_sets(it.a, it.b)) {
			G[it.a].push_back({ it.b, it.w });
			G[it.b].push_back({ it.a, it.w });
		}
	}
	h[1] = 1;
	dfs(1, 1, 1e9 + 10);
	while (q--) {
		int s, t;
		cin >> s >> t;
		cout << val(s, t) << "\n";
	}
}
| # | 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... |