This submission is migrated from previous version of oj.uz, which used different machine for grading. This submission may have different result if resubmitted.
#include <bits/stdc++.h>
using namespace std;
#define int long long
mt19937_64 RNG(chrono::steady_clock::now().time_since_epoch().count());
const int N = 4e5 + 5;
struct reach_tree_node {
int val, par, max_par;
} *rt_node[N * 2];
vector<array<int, 2> > g[N];
vector<array<int, 2> > dist(N);
vector<int> startNodes;
int n, m;
int DP[19][N], depth[N];
int Find(int x) {
if(rt_node[x]->max_par == x) {
return x;
}
return rt_node[x]->max_par = Find(rt_node[x]->max_par);
}
void Unite(int a, int b, int fakeNodeIdx, int valFeed) {
a = Find(a), b = Find(b);
//cout << "a = " << a << ", b = " << b << "\n";
rt_node[a]->par = fakeNodeIdx;
rt_node[b]->par = fakeNodeIdx;
rt_node[a]->max_par = fakeNodeIdx;
rt_node[b]->max_par = fakeNodeIdx;
rt_node[fakeNodeIdx]->val = valFeed;
}
void dijkstra() {
for(int i = 0; i < N; i++) {
dist[i][0] = 1e15;
dist[i][1] = i;
}
priority_queue<array<int, 2>, vector<array<int, 2> >, greater<array<int, 2> > > pq;
for(int i = 0; i < startNodes.size(); i++) {
dist[startNodes[i]][0] = 0;
pq.push({dist[startNodes[i]][0], startNodes[i]});
}
while(!pq.empty()) {
int cur_dist = pq.top()[0], node = pq.top()[1];
pq.pop();
if(cur_dist != dist[node][0]) {
continue;
}
for(int i = 0; i < g[node].size(); i++) {
if(dist[g[node][i][0]][0] > dist[node][0] + g[node][i][1]) {
dist[g[node][i][0]][0] = dist[node][0] + g[node][i][1];
pq.push({dist[g[node][i][0]][0], g[node][i][0]});
}
}
}
}
int LCA(int x, int y) {
if(depth[x] > depth[y]) {
swap(x, y);
}
int diff = depth[y] - depth[x];
for(int i = 18; i >= 0; i--) {
if((1 << i) <= diff) {
diff -= (1 << i);
y = DP[i][y];
}
}
if(x == y) {
return x;
}
for(int i = 18; i >= 0; i--) {
if(DP[i][x] != DP[i][y]) {
x = DP[i][x];
y = DP[i][y];
}
}
return DP[0][x];
}
void Solve() {
cin >> n >> m;
for(int i = 1; i <= m; i++) {
int u, v, w;
cin >> u >> v >> w;
g[u].push_back({v, w});
g[v].push_back({u, w});
}
int startLen;
cin >> startLen;
for(int i = 0; i < startLen; i++) {
int node;
cin >> node;
startNodes.push_back(node);
}
dijkstra();
/*for(int i = 1; i <= n; i++) {
cout << dist[i][0] << " ";
}
cout << "\n";*/
for(int i = 1; i <= 2 * n; i++) {
rt_node[i] = new reach_tree_node();
rt_node[i]->max_par = i;
rt_node[i]->par = i;
rt_node[i]->val = dist[i][0];
}
int fakeNode = n + 1;
bool visited[N];
for(int i = 0; i < N; i++) {
visited[i] = false;
}
sort(dist.begin() + 1, dist.begin() + 1 + n);
reverse(dist.begin() + 1, dist.begin() + 1 + n);
for(int i = 1; i <= n; i++) {
int node = dist[i][1];
visited[node] = true;
for(int j = 0; j < g[node].size(); j++) {
if(visited[g[node][j][0]]) {
if(Find(node) == Find(g[node][j][0])) {
continue;
}
Unite(node, g[node][j][0], fakeNode++, dist[i][0]);
//cout << "node = " << node << ", g[node][j][0] = " << g[node][j][0] << ", fakeNode = " << fakeNode << ", dist[i][0] = " << dist[i][0] << "\n";
//cout << "Find(node) = " << Find(node) << ", Find(g[node][j][0]) = " << Find(g[node][j][0]) << "\n";
}
}
}
for(int i = 1; i < fakeNode; i++) {
DP[0][i] = rt_node[i]->par;
}
for(int i = 1; i < 19; i++) {
for(int j = 1; j < fakeNode; j++) {
if(DP[i - 1][j] == -1) {
DP[i][j] = -1;
}
else {
DP[i][j] = DP[i - 1][DP[i - 1][j]];
}
}
}
depth[fakeNode - 1] = 0;
for(int i = fakeNode - 2; i > 0; i--) {
depth[i] = depth[rt_node[i]->par] + 1;
}
int q;
cin >> q;
while(q--) {
int s, e;
cin >> s >> e;
int lca = LCA(s, e);
cout << rt_node[lca]->val << "\n";
}
}
int32_t main() {
auto begin = std::chrono::high_resolution_clock::now();
ios_base::sync_with_stdio(0);
cin.tie(0);
int t = 1;
//cin >> t;
while(t--) {
Solve();
}
auto end = std::chrono::high_resolution_clock::now();
auto elapsed = std::chrono::duration_cast<std::chrono::nanoseconds>(end - begin);
cerr << "Time measured: " << elapsed.count() * 1e-9 << " seconds.\n";
return 0;
}
Compilation message (stderr)
plan.cpp: In function 'void dijkstra()':
plan.cpp:42:19: warning: comparison of integer expressions of different signedness: 'long long int' and 'std::vector<long long int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
42 | for(int i = 0; i < startNodes.size(); i++) {
| ~~^~~~~~~~~~~~~~~~~~~
plan.cpp:52:20: warning: comparison of integer expressions of different signedness: 'long long int' and 'std::vector<std::array<long long int, 2> >::size_type' {aka 'long unsigned int'} [-Wsign-compare]
52 | for(int i = 0; i < g[node].size(); i++) {
| ~~^~~~~~~~~~~~~~~~
plan.cpp: In function 'void Solve()':
plan.cpp:120:20: warning: comparison of integer expressions of different signedness: 'long long int' and 'std::vector<std::array<long long int, 2> >::size_type' {aka 'long unsigned int'} [-Wsign-compare]
120 | for(int j = 0; j < g[node].size(); j++) {
| ~~^~~~~~~~~~~~~~~~
# | 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... |