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

#include <algorithm>
#include <cstdio>
#include <queue>

#define rep(i, n) for (int i = 0; i < (n); ++i)

using namespace std;

typedef pair<int, int> P;
typedef pair<int, P> Q;
typedef vector<int> V;

const int inf = 1e8;
const int bs = 300;

struct E {
  E(int t, int c) : t(t), c(c) {}
  int t, c;
};

int n, m, k, q;
vector<E> g[100000];
P z[100000];
int d[100000];
int sd[100000];
vector<Q> f;
vector<int> v[334];
int r[100000];
int up[100000];
int ur[100000];

void ut_init() {
  rep(i, n) {
    up[i] = i;
    ur[i] = 0;
  }
}
int ut_find(int i) { return up[i] == i ? i : up[i] = ut_find(up[i]); }
bool ut_same(int i, int j) { return ut_find(i) == ut_find(j); }
void ut_unite(int i, int j) {
  int p = ut_find(i);
  int q = ut_find(j);
  if (p == q) {
    return;
  }
  if (ur[p] > ur[q]) {
    up[q] = p;
  } else {
    up[p] = q;
    if (ur[p] == ur[q]) {
      ++ur[q];
    }
  }
}

void solve() {
  rep(i, n) {
    rep(j, g[i].size()) {
      E e = g[i][j];
      if (i < e.t) {
        f.push_back(Q(min(d[i], d[e.t]), P(i, e.t)));
      }
    }
  }
  sort(f.begin(), f.end(), greater<Q>());

  int nb = (n + bs - 1) / bs;

  ut_init();

  V x;
  rep(i, q) { x.push_back(i); }

  int nf = 0;
  rep(i, nb) {
    int a = i * bs;
    int b = min((i + 1) * bs, n);
    while (nf < f.size() && f[nf].first >= sd[b - 1]) {
      ut_unite(f[nf].second.first, f[nf].second.second);
      ++nf;
    }

    V y;
    rep(j, x.size()) {
      if (ut_same(z[x[j]].first, z[x[j]].second)) {
        v[i].push_back(x[j]);
      } else {
        y.push_back(x[j]);
      }
    }
    x = y;
  }

  /*
  rep(i, f.size()){
          printf("f = %d, (%d, %d)\\n", f[i].first, f[i].second.first,
  f[i].second.second);
  }
  */

  ut_init();

  nf = 0;
  rep(i, nb) {
    int a = i * bs;
    int b = min((i + 1) * bs, n);
    for (int j = a; j < b; ++j) {
      while (nf < f.size() && f[nf].first >= sd[j]) {
        ut_unite(f[nf].second.first, f[nf].second.second);
        ++nf;
      }

      // printf("nf = %d, sd[j] = %d, j = %d\\n", nf, sd[j], j);

      V y;
      rep(k, v[i].size()) {
        if (ut_same(z[v[i][k]].first, z[v[i][k]].second)) {
          r[v[i][k]] = sd[j];
        } else {
          y.push_back(v[i][k]);
        }
      }
      v[i] = y;
    }
  }
}

int main() {
  scanf("%d%d%d%d", &n, &m, &k, &q);
  rep(i, m) {
    int a, b, c;
    scanf("%d%d%d", &a, &b, &c);
    g[--a].push_back(E(--b, c));
    g[b].push_back(E(a, c));
  }

  fill_n(d, n, inf);

  priority_queue<P, vector<P>, greater<P>> pq;
  rep(i, k) {
    int f;
    scanf("%d", &f);
    d[--f] = 0;
    pq.push(P(0, f));
  }
  while (!pq.empty()) {
    P v = pq.top();
    pq.pop();
    if (v.first > d[v.second]) {
      continue;
    }
    rep(i, g[v.second].size()) {
      E e = g[v.second][i];
      if (d[e.t] > v.first + e.c) {
        d[e.t] = v.first + e.c;
        pq.push(P(d[e.t], e.t));
      }
    }
  }

  rep(i, q) {
    int s, t;
    scanf("%d%d", &s, &t);
    z[i] = P(s - 1, t - 1);
  }

  rep(i, n) { sd[i] = d[i]; }
  sort(sd, sd + n, greater<int>());

  solve();

  rep(i, q) { printf("%d\\n", r[i]); }
  return 0;
}

Error: TLE

Fixed submission:

#include <algorithm>
#include <cstdio>
#include <queue>

#define rep(i, n) for (int i = 0; i < (n); ++i)

using namespace std;

typedef pair<int, int> P;
typedef vector<int> V;

const int inf = 1e8;
const int bs = 300;

struct E {
  E(int t, int c) : t(t), c(c) {}
  int t, c;
};

int n, m, k, q;
vector<E> g[100000];
P z[100000];
int d[100000];
int sd[100000];
V v[334];
int r[100000];
int up[100000];
int ur[100000];

void ut_init() {
  rep(i, n) {
    up[i] = i;
    ur[i] = 0;
  }
}
int ut_find(int i) { return up[i] == i ? i : up[i] = ut_find(up[i]); }
bool ut_same(int i, int j) { return ut_find(i) == ut_find(j); }
void ut_unite(int i, int j) {
  int p = ut_find(i);
  int q = ut_find(j);
  if (p == q) {
    return;
  }
  if (ur[p] > ur[q]) {
    up[q] = p;
  } else {
    up[p] = q;
    if (ur[p] == ur[q]) {
      ++ur[q];
    }
  }
}

void solve() {
  rep(i, n) { sd[i] = d[i]; }
  sort(sd, sd + n);

  int nb = (n + bs - 1) / bs;

  V x;
  rep(i, q) { x.push_back(i); }

  for (int i = nb - 1; i >= 0; --i) {
    int c = sd[i * bs];

    ut_init();
    rep(j, n) {
      rep(k, g[j].size()) {
        E e = g[j][k];
        if (d[j] >= c && d[e.t] >= c) {
          ut_unite(j, e.t);
        }
      }
    }

    V y;
    rep(j, x.size()) {
      int s = z[x[j]].first;
      int t = z[x[j]].second;
      if (ut_same(s, t)) {
        v[i].push_back(x[j]);
      } else {
        y.push_back(x[j]);
      }
    }
    x = y;
  }

  rep(a, nb) {
    for (int i = min((a + 1) * bs, n) - 1; i >= a * bs; --i) {
      int c = sd[i];

      ut_init();
      rep(j, n) {
        rep(k, g[j].size()) {
          E e = g[j][k];
          if (d[j] >= c && d[e.t] >= c) {
            ut_unite(j, e.t);
          }
        }
      }

      V y;
      rep(j, v[a].size()) {
        int s = z[v[a][j]].first;
        int t = z[v[a][j]].second;
        if (ut_same(s, t)) {
          r[v[a][j]] = c;
        } else {
          y.push_back(v[a][j]);
        }
      }
      v[a] = y;
    }
  }
}

int main() {
  scanf("%d%d%d%d", &n, &m, &k, &q);
  rep(i, m) {
    int a, b, c;
    scanf("%d%d%d", &a, &b, &c);
    g[--a].push_back(E(--b, c));
    g[b].push_back(E(a, c));
  }

  fill_n(d, n, inf);

  priority_queue<P, vector<P>, greater<P>> pq;
  rep(i, k) {
    int f;
    scanf("%d", &f);
    d[--f] = 0;
    pq.push(P(0, f));
  }
  while (!pq.empty()) {
    P v = pq.top();
    pq.pop();
    if (v.first > d[v.second]) {
      continue;
    }
    rep(i, g[v.second].size()) {
      E e = g[v.second][i];
      if (d[e.t] > v.first + e.c) {
        d[e.t] = v.first + e.c;
        pq.push(P(d[e.t], e.t));
      }
    }
  }

  rep(i, q) {
    int s, t;
    scanf("%d%d", &s, &t);
    z[i] = P(s - 1, t - 1);
  }

  solve();

  rep(i, q) { printf("%d\\n", r[i]); }
  return 0;
}