Problem p00498 (C++)

Buggy submission (status: Runtime Error):
#include <algorithm>
#include <cstdio>
#include <functional>
#include <queue>
#include <vector>
#pragma warning(disable : 4996)
FILE *in = freopen("./input.txt", "r", stdin);
using namespace std;
struct edge {
  int to, cost;
};
bool operator<(const edge &e1, const edge &e2) { return e1.cost < e2.cost; }
vector<int> par;
int root(int x) {
  if (x == par[x])
    return x;
  return par[x] = root(par[x]);
}
void unite(int x, int y) {
  x = root(x);
  y = root(y);
  if (x == y)
    return;
  par[x] = y;
}
bool same(int x, int y) { return root(x) == root(y); }
vector<int> depth;
vector<vector<int>> parent, val;
int lca(int x, int y) {
  if (depth[x] < depth[y])
    swap(x, y);
  for (int i = 16; i >= 0; i--) {
    if ((depth[x] - depth[y]) >= (1 << i))
      x = parent[i][x];
  }
  for (int i = 16; i >= 0; i--) {
    if (parent[i][x] != parent[i][y]) {
      x = parent[i][x];
      y = parent[i][y];
    }
  }
  while (x != y) {
    x = parent[0][x];
    y = parent[0][y];
  }
  return x;
}
int query(int x, int y) {
  int z = lca(x, y);
  int t1 = depth[x] - depth[z], t2 = depth[y] - depth[z];
  int ret = 1999999999;
  for (int i = 16; i >= 0; i--) {
    if (t1 & (1 << i))
      ret = min(ret, val[i][x]), x = parent[i][x];
    if (t2 & (1 << i))
      ret = min(ret, val[i][y]), y = parent[i][y];
  }
  return ret;
}
void findpar(int pos, int pre, vector<vector<edge>> &G) {
  parent[0][pos] = pre;
  for (edge e : G[pos]) {
    if (e.to != pre) {
      val[0][e.to] = e.cost;
      depth[e.to] = depth[pos] + 1;
      findpar(e.to, pos, G);
    }
  }
}
int N, M, K, Q, f, t1, t2;
int main() {
  scanf("%d%d%d%d", &N, &M, &K, &Q);
  vector<vector<edge>> G(N);
  vector<int> a(M), b(M), c(M);
  for (int i = 0; i < M; i++) {
    scanf("%d%d%d", &a[i], &b[i], &c[i]);
    a[i]--, b[i]--;
    G[a[i]].push_back(edge{b[i], c[i]});
    G[b[i]].push_back(edge{a[i], c[i]});
  }
  vector<int> dist(N, 1999999999);
  priority_queue<edge> que;
  for (int i = 0; i < K; i++) {
    scanf("%d", &f);
    f--;
    dist[f] = 0;
    que.push(edge{f, 0});
  }
  while (!que.empty()) {
    edge u = que.top();
    que.pop();
    for (edge e : G[u.to]) {
      if (dist[e.to] > dist[u.to] + e.cost) {
        dist[e.to] = dist[u.to] + e.cost;
        que.push(edge{e.to, -dist[e.to]});
      }
    }
  }
  vector<pair<int, int>> s;
  for (int i = 0; i < M; i++) {
    c[i] = min(dist[a[i]], dist[b[i]]);
    s.push_back(make_pair(c[i], i));
  }
  sort(s.begin(), s.end(), greater<pair<int, int>>());
  par.resize(N);
  for (int i = 0; i < N; i++)
    par[i] = i;
  vector<vector<edge>> G2(N);
  for (int i = 0; i < M; i++) {
    int r1 = a[s[i].second], r2 = b[s[i].second], r3 = c[s[i].second];
    ;
    if (!same(r1, r2)) {
      unite(r1, r2);
      G2[r1].push_back(edge{r2, r3});
      G2[r2].push_back(edge{r1, r3});
    }
  }
  parent = vector<vector<int>>(17, vector<int>(N));
  val = vector<vector<int>>(17, vector<int>(N));
  depth.resize(N);
  findpar(0, -1, G2);
  for (int i = 1; i < 17; i++) {
    for (int j = 0; j < N; j++) {
      if (parent[i - 1][j] == -1)
        parent[i][j] = -1, val[i][j] = 1999999999;
      else
        parent[i][j] = parent[i - 1][parent[i - 1][j]],
        val[i][j] = min(val[i - 1][j], val[i - 1][parent[i - 1][j]]);
    }
  }
  while (Q--) {
    scanf("%d%d", &t1, &t2);
    t1--, t2--;
    printf("%d\n", query(t1, t2));
  }
  return 0;
}

Fixed submission:
#include <algorithm>
#include <cstdio>
#include <functional>
#include <queue>
#include <vector>
using namespace std;
struct edge {
  int to, cost;
};
bool operator<(const edge &e1, const edge &e2) { return e1.cost < e2.cost; }
vector<int> par;
int root(int x) {
  if (x == par[x])
    return x;
  return par[x] = root(par[x]);
}
void unite(int x, int y) {
  x = root(x);
  y = root(y);
  if (x == y)
    return;
  par[x] = y;
}
bool same(int x, int y) { return root(x) == root(y); }
vector<int> depth;
vector<vector<int>> parent, val;
int lca(int x, int y) {
  if (depth[x] < depth[y])
    swap(x, y);
  for (int i = 16; i >= 0; i--) {
    if ((depth[x] - depth[y]) >= (1 << i))
      x = parent[i][x];
  }
  for (int i = 16; i >= 0; i--) {
    if (parent[i][x] != parent[i][y]) {
      x = parent[i][x];
      y = parent[i][y];
    }
  }
  while (x != y) {
    x = parent[0][x];
    y = parent[0][y];
  }
  return x;
}
int query(int x, int y) {
  int z = lca(x, y);
  int t1 = depth[x] - depth[z], t2 = depth[y] - depth[z];
  int ret = 1999999999;
  for (int i = 16; i >= 0; i--) {
    if (t1 & (1 << i))
      ret = min(ret, val[i][x]), x = parent[i][x];
    if (t2 & (1 << i))
      ret = min(ret, val[i][y]), y = parent[i][y];
  }
  return ret;
}
void findpar(int pos, int pre, vector<vector<edge>> &G) {
  parent[0][pos] = pre;
  for (edge e : G[pos]) {
    if (e.to != pre) {
      val[0][e.to] = e.cost;
      depth[e.to] = depth[pos] + 1;
      findpar(e.to, pos, G);
    }
  }
}
int N, M, K, Q, f, t1, t2;
int main() {
  scanf("%d%d%d%d", &N, &M, &K, &Q);
  vector<vector<edge>> G(N);
  vector<int> a(M), b(M), c(M);
  for (int i = 0; i < M; i++) {
    scanf("%d%d%d", &a[i], &b[i], &c[i]);
    a[i]--, b[i]--;
    G[a[i]].push_back(edge{b[i], c[i]});
    G[b[i]].push_back(edge{a[i], c[i]});
  }
  vector<int> dist(N, 1999999999);
  priority_queue<edge> que;
  for (int i = 0; i < K; i++) {
    scanf("%d", &f);
    f--;
    dist[f] = 0;
    que.push(edge{f, 0});
  }
  while (!que.empty()) {
    edge u = que.top();
    que.pop();
    for (edge e : G[u.to]) {
      if (dist[e.to] > dist[u.to] + e.cost) {
        dist[e.to] = dist[u.to] + e.cost;
        que.push(edge{e.to, -dist[e.to]});
      }
    }
  }
  vector<pair<int, int>> s;
  for (int i = 0; i < M; i++) {
    c[i] = min(dist[a[i]], dist[b[i]]);
    s.push_back(make_pair(c[i], i));
  }
  sort(s.begin(), s.end(), greater<pair<int, int>>());
  par.resize(N);
  for (int i = 0; i < N; i++)
    par[i] = i;
  vector<vector<edge>> G2(N);
  for (int i = 0; i < M; i++) {
    int r1 = a[s[i].second], r2 = b[s[i].second], r3 = c[s[i].second];
    ;
    if (!same(r1, r2)) {
      unite(r1, r2);
      G2[r1].push_back(edge{r2, r3});
      G2[r2].push_back(edge{r1, r3});
    }
  }
  parent = vector<vector<int>>(17, vector<int>(N));
  val = vector<vector<int>>(17, vector<int>(N));
  depth.resize(N);
  findpar(0, -1, G2);
  for (int i = 1; i < 17; i++) {
    for (int j = 0; j < N; j++) {
      if (parent[i - 1][j] == -1)
        parent[i][j] = -1, val[i][j] = 1999999999;
      else
        parent[i][j] = parent[i - 1][parent[i - 1][j]],
        val[i][j] = min(val[i - 1][j], val[i - 1][parent[i - 1][j]]);
    }
  }
  while (Q--) {
    scanf("%d%d", &t1, &t2);
    t1--, t2--;
    printf("%d\n", query(t1, t2));
  }
  return 0;
}