Problem p00498 (C++)

Buggy submission (status: Memory Limit Exceeded):
#include <cstdio>
#include <functional>
#include <queue>
#include <set>
#include <utility>
#include <vector>
using namespace std;
typedef pair<int, int> P;
const int INF = 1 << 30;
struct edge {
  int p, q, c;
  edge(int p, int q, int c) {
    this->p = p;
    this->q = q;
    this->c = c;
  }
  bool operator<(const edge &X) const { return (this->c) < X.c; }
};
set<edge> query[100000];
int ans[100000];
int par[100000];
vector<P> G[100000];
int dist[100000];
int find(int x) {
  if (par[x] == x)
    return x;
  return par[x] = find(par[x]);
}
void unite(int x, int y, int c) {
  x = find(x);
  y = find(y);
  if (x == y)
    return;
  if (query[x].size() > query[y].size())
    swap(x, y);
  for (auto itr = query[x].begin(); itr != query[x].end(); itr++) {
    if (query[y].find(*itr) == query[y].end()) {
      query[y].insert(*itr);
    } else {
      ans[itr->c] = c;
    }
  }
  par[x] = y;
}
bool same(int x, int y) { return find(x) == find(y); }
int main() {
  int N, M, K, Q;
  scanf("%d %d %d %d", &N, &M, &K, &Q);
  for (int i = 0; i < M; i++) {
    int A, B, L;
    scanf("%d %d %d", &A, &B, &L);
    A--;
    B--;
    G[A].push_back(P(B, L));
    G[B].push_back(P(A, L));
  }
  fill(dist, dist + N, INF);
  priority_queue<P, vector<P>, greater<P>> que;
  for (int i = 0; i < K; i++) {
    int F;
    scanf("%d", &F);
    F--;
    dist[F] = 0;
    que.push(P(0, F));
  }
  while (!que.empty()) {
    P p = que.top();
    que.pop();
    int x = p.second, c = p.first;
    if (dist[x] < c)
      continue;
    for (int i = 0; i < G[x].size(); i++) {
      int to = G[x][i].first;
      int cost = G[x][i].second;
      if (dist[to] > (c + cost)) {
        dist[to] = c + cost;
        que.push(P(dist[to], to));
      }
    }
  }
  priority_queue<edge> E;
  for (int i = 0; i < N; i++) {
    for (int j = 0; j < G[i].size(); j++) {
      int to = G[i][j].first;
      E.push(edge(i, to, min(dist[i], dist[to])));
    }
  }
  for (int i = 0; i < Q; i++) {
    int S, T;
    scanf("%d %d", &S, &T);
    S--;
    T--;
    if (S > T)
      swap(S, T);
    query[S].insert(edge(S, T, i));
    query[T].insert(edge(S, T, i));
  }
  for (int i = 0; i < N; i++) {
    par[i] = i;
  }
  while (!E.empty()) {
    edge e = E.top();
    E.pop();
    if (!same(e.p, e.q)) {
      unite(e.p, e.q, e.c);
    }
  }
  for (int i = 0; i < Q; i++) {
    printf("%d\n", ans[i]);
  }
}

Fixed submission:
#include <cstdio>
#include <functional>
#include <queue>
#include <set>
#include <utility>
#include <vector>
using namespace std;
typedef pair<int, int> P;
const int INF = 1 << 30;
struct edge {
  int p, q, c;
  edge(int p, int q, int c) {
    this->p = p;
    this->q = q;
    this->c = c;
  }
  bool operator<(const edge &X) const { return (this->c) < X.c; }
};
set<edge> query[100000];
int ans[100000];
int par[100000];
vector<P> G[100000];
int dist[100000];
int find(int x) {
  if (par[x] == x)
    return x;
  return par[x] = find(par[x]);
}
void unite(int x, int y, int c) {
  x = find(x);
  y = find(y);
  if (x == y)
    return;
  if (query[x].size() > query[y].size())
    swap(x, y);
  for (auto itr = query[x].begin(); itr != query[x].end(); itr++) {
    if (query[y].find(*itr) == query[y].end()) {
      query[y].insert(*itr);
    } else {
      ans[itr->c] = c;
    }
  }
  query[x].clear();
  par[x] = y;
}
bool same(int x, int y) { return find(x) == find(y); }
int main() {
  int N, M, K, Q;
  scanf("%d %d %d %d", &N, &M, &K, &Q);
  for (int i = 0; i < M; i++) {
    int A, B, L;
    scanf("%d %d %d", &A, &B, &L);
    A--;
    B--;
    G[A].push_back(P(B, L));
    G[B].push_back(P(A, L));
  }
  fill(dist, dist + N, INF);
  priority_queue<P, vector<P>, greater<P>> que;
  for (int i = 0; i < K; i++) {
    int F;
    scanf("%d", &F);
    F--;
    dist[F] = 0;
    que.push(P(0, F));
  }
  while (!que.empty()) {
    P p = que.top();
    que.pop();
    int x = p.second, c = p.first;
    if (dist[x] < c)
      continue;
    for (int i = 0; i < G[x].size(); i++) {
      int to = G[x][i].first;
      int cost = G[x][i].second;
      if (dist[to] > (c + cost)) {
        dist[to] = c + cost;
        que.push(P(dist[to], to));
      }
    }
  }
  priority_queue<edge> E;
  for (int i = 0; i < N; i++) {
    for (int j = 0; j < G[i].size(); j++) {
      int to = G[i][j].first;
      E.push(edge(i, to, min(dist[i], dist[to])));
    }
  }
  for (int i = 0; i < Q; i++) {
    int S, T;
    scanf("%d %d", &S, &T);
    S--;
    T--;
    if (S > T)
      swap(S, T);
    query[S].insert(edge(S, T, i));
    query[T].insert(edge(S, T, i));
  }
  for (int i = 0; i < N; i++) {
    par[i] = i;
  }
  while (!E.empty()) {
    edge e = E.top();
    E.pop();
    if (!same(e.p, e.q)) {
      unite(e.p, e.q, e.c);
    }
  }
  for (int i = 0; i < Q; i++) {
    printf("%d\n", ans[i]);
  }
}