Problem p00498 (C++) — buggy submission, verdict: Time Limit Exceeded

#include <algorithm>
#include <cstring>
#include <iostream>
#include <queue>
#include <vector>

using namespace std;

#define MAX_N (100000)
typedef pair<int, int> pint;
typedef pair<int, pint> ppi;
struct edge {
  int dst, weight;
};
vector<edge> road[MAX_N];
vector<ppi> r2;
vector<int> road2[MAX_N];
int d[MAX_N], n;
int inf = 1000000000;

struct UnionFind {
  int par[MAX_N];
  void init(int n) {
    for (int i = 0; i < n; i++)
      par[i] = i;
  }
  int find(int x) {
    if (x == par[x])
      return (x);
    return (par[x] = find(par[x]));
  }
  void unite(int x, int y) {
    x = find(x);
    y = find(y);
    if (x == y)
      return;
    par[x] = y;
  }
  bool same(int x, int y) { return (find(x) == find(y)); }
};

int par[20][MAX_N];
int depth[MAX_N];
int mn[20][MAX_N];
void dfs(int v, int p, int dep) {
  par[0][v] = p;
  mn[0][v] = min(d[v], p > 0 ? d[p] : inf);
  depth[v] = dep;
  for (int i = 0; i < road2[v].size(); ++i) {
    if (road2[v][i] != p) {
      dfs(road2[v][i], v, dep + 1);
    }
  }
}
void lca_init() {
  dfs(0, -1, 0);
  for (int k = 0; k < 19; ++k) {
    for (int i = 0; i < n; ++i) {
      if (par[k][i] < 0)
        par[k + 1][i] = -1;
      else {
        par[k + 1][i] = par[k][par[k][i]];
        mn[k + 1][i] = min(mn[k][i], mn[k][par[k][i]]);
      }
    }
  }
}
int lca(int a, int b) {
  int res = inf;
  if (depth[a] > depth[b])
    swap(a, b);
  for (int k = 0; k < 20; ++k) {
    if ((depth[b] - depth[a]) >> k & 1) {
      res = min(res, mn[k][b]);
      b = par[k][b];
    }
  }
  if (a == b)
    return min(res, d[a]);
  for (int k = 19; k >= 0; --k) {
    if (par[k][a] != par[k][b]) {
      res = min(res, min(mn[k][a], mn[k][b]));
      a = par[k][a];
      b = par[k][b];
    }
  }
  return min(res, min(mn[0][a], mn[0][b]));
}

int main() {
  priority_queue<pint, vector<pint>, greater<pint>> pq;
  int m, k, q;
  cin >> n >> m >> k >> q;
  int a, b, l;
  edge ed;
  for (int i = 0; i < m; ++i) {
    cin >> a >> b >> l;
    ed.dst = b - 1;
    ed.weight = l;
    road[a - 1].push_back(ed);
    ed.dst = a - 1;
    ed.weight = l;
    road[b - 1].push_back(ed);
  }
  for (int i = 0; i < n; ++i)
    d[i] = inf;
  for (int i = 0; i < k; ++i) {
    cin >> a;
    d[a - 1] = 0;
    pq.push(make_pair(0, a - 1));
  }
  while (!pq.empty()) {
    pint pi = pq.top();
    pq.pop();
    int t = pi.second;
    for (vector<edge>::iterator it = road[t].begin(); it != road[t].end();
         ++it) {
      if (d[it->dst] > d[t] + it->weight) {
        d[it->dst] = d[t] + it->weight;
        pq.push(make_pair(d[it->dst], it->dst));
      }
    }
  }
  for (int i = 0; i < n; ++i) {
    for (int j = 0; j < road[i].size(); ++j) {
      r2.push_back(make_pair(min(d[i], d[road[i][j].dst]),
                             make_pair(i, road[i][j].dst)));
    }
  }
  sort(r2.begin(), r2.end(), greater<ppi>());
  UnionFind uf;
  uf.init(n);

  for (int i = 0; i < r2.size(); ++i) {
    ppi rr = r2[i];
    if (!uf.same(rr.second.first, rr.second.second)) {
      uf.unite(rr.second.first, rr.second.second);
      road2[rr.second.first].push_back(rr.second.second);
      road2[rr.second.second].push_back(rr.second.first);
    }
  }
  lca_init();
  for (int i = 0; i < q; i++) {
    cin >> a >> b;
    cout << lca(a - 1, b - 1) << endl;
  }
  return 0;
}

Error: TLE

Fixed submission:

#include <cstring>
#include <iostream>
#include <queue>
#include <vector>

using namespace std;

typedef pair<int, int> pint;
struct edge {
  int dst, weight;
};
vector<edge> road[100000];
int d[100000];
bool visit[100000];
int inf = 1000000000;

int dfs(int src, int dst, int mn) {
  mn = min(d[src], mn);
  if (src == dst)
    return mn;
  int mx = 0;
  for (vector<edge>::iterator it = road[src].begin(); it != road[src].end();
       ++it) {
    if (!visit[it->dst]) {
      visit[it->dst] = 1;
      mx = max(mx, dfs(it->dst, dst, mn));
      visit[it->dst] = 0;
    }
  }
  return mx;
}

int main() {
  priority_queue<pint, vector<pint>, greater<pint>> pq;
  int n, m, k, q;
  cin >> n >> m >> k >> q;
  int a, b, l;
  edge ed;
  for (int i = 0; i < m; ++i) {
    cin >> a >> b >> l;
    ed.dst = b - 1;
    ed.weight = l;
    road[a - 1].push_back(ed);
    ed.dst = a - 1;
    ed.weight = l;
    road[b - 1].push_back(ed);
  }
  for (int i = 0; i < n; ++i)
    d[i] = inf;
  for (int i = 0; i < k; ++i) {
    cin >> a;
    d[a - 1] = 0;
    pq.push(make_pair(0, a - 1));
  }
  while (!pq.empty()) {
    pint pi = pq.top();
    pq.pop();
    int t = pi.second;
    for (vector<edge>::iterator it = road[t].begin(); it != road[t].end();
         ++it) {
      if (d[it->dst] > d[t] + it->weight) {
        d[it->dst] = d[t] + it->weight;
        pq.push(make_pair(d[it->dst], it->dst));
      }
    }
  }
  int sr, dt;
  for (int i = 0; i < q; ++i) {
    cin >> sr >> dt;
    memset(visit, 0, sizeof(visit));
    visit[sr - 1] = 1;
    cout << dfs(sr - 1, dt - 1, inf) << endl;
  }
  return 0;
}