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

#include <bits/stdc++.h>
using namespace std;

#define int long long
typedef vector<int> vint;
typedef pair<int, int> pint;
typedef vector<pint> vpint;
#define rep(i, n) for (int i = 0; i < (n); i++)
#define reps(i, f, n) for (int i = (f); i < (n); i++)
#define all(v) (v).begin(), (v).end()
#define each(it, v)                                                            \\
  for (__typeof((v).begin()) it = (v).begin(); it != (v).end(); it++)
#define pb push_back
#define fi first
#define se second
template <typename A, typename B> inline void chmin(A &a, B b) {
  if (a > b)
    a = b;
}
template <typename A, typename B> inline void chmax(A &a, B b) {
  if (a < b)
    a = b;
}

struct LinkCutTree {
  ;
  struct Node {
    Node *lp, *rp, *pp;
    bool rev;
    int val, agg;
    Node() : lp(0), rp(0), pp(0), rev(0) {}
    bool isRoot() { return !pp || (pp->lp != this && pp->rp != this); }

    void push() {
      if (!rev)
        return;
      if (lp)
        lp->rev ^= 1;
      if (rp)
        rp->rev ^= 1;
      swap(lp, rp);
      rev = false;
    }

    void push_all() {
      if (!isRoot())
        pp->push_all();
      push();
      if (lp)
        lp->push();
      if (rp)
        rp->push();
    }

    void update() {
      agg = val;
      if (lp)
        chmin(agg, lp->agg);
      if (rp)
        chmin(agg, rp->agg);
    }

    void rotR() {
      Node *q = pp, *r = q->pp;
      if ((q->lp = rp))
        rp->pp = q;
      rp = q;
      q->pp = this;
      if ((pp = r)) {
        if (r->lp == q)
          r->lp = this;
        if (r->rp == q)
          r->rp = this;
      }
      q->update();
      update();
    }

    void rotL() {
      Node *q = pp, *r = q->pp;
      if ((q->rp = lp))
        lp->pp = q;
      lp = q;
      q->pp = this;
      if ((pp = r)) {
        if (r->lp == q)
          r->lp = this;
        if (r->rp == q)
          r->rp = this;
      }
      q->update();
      update();
    }

    void splay() {
      push_all();
      while (!isRoot()) {
        Node *q = pp;
        if (q->isRoot()) {
          if (q->lp == this)
            rotR();
          else
            rotL();
        } else {
          Node *r = q->pp;
          if (r->lp == q) {
            if (q->lp == this) {
              q->rotR();
              rotR();
            } else {
              rotL();
              rotR();
            }
          } else {
            if (q->rp == this) {
              q->rotL();
              rotL();
            } else {
              rotR();
              rotL();
            }
          }
        }
      }
    }

    void expose() {
      Node *rp = NULL;
      for (Node *p = this; p; p = p->pp) {
        p->splay();
        p->rp = rp;
        rp = p;
        p->update();
      }
      splay();
    }
  };

  Node *nodes;
  LinkCutTree(int n) { nodes = new Node[n]; }

  //???(v->v??????)?????????
  void cut(int v) {
    nodes[v].expose();
    Node *p = nodes[v].lp;
    nodes[v].lp = NULL;
    p->pp = NULL;
    nodes[v].update();
  }

  //???(v->u)?????????
  void link(int v, int u) {
    nodes[v].expose();
    nodes[u].expose();
    nodes[v].pp = &nodes[u];
    nodes[u].rp = &nodes[v];
    nodes[u].update();
  }

  int lca(int a, int b) {
    nodes[a].expose();
    nodes[b].expose();

    bool sameTree = false;
    Node *ret = &nodes[a];
    for (Node *x = &nodes[a]; x; x = x->pp) {
      if (x->pp && x->isRoot())
        ret = x->pp;
      if (x == &nodes[b])
        sameTree = true;
    }
    return sameTree ? (ret - nodes) : -1;
  }

  void evert(int v) {
    nodes[v].expose();
    nodes[v].rev ^= 1;
  }

  int findRoot(int v) {
    Node *p = &nodes[v];
    p->expose();
    while (p->lp)
      p = p->lp;
    p->splay();
    return p - nodes;
  }

  int query(int u, int v) {
    evert(u);
    nodes[v].expose();
    return nodes[v].agg;
  }
};

const int INF = 1001001001ll;

int N, M, K, Q;
int A[222222], B[222222], C[222222];
vpint G[222222];
int dist[222222];
signed main() {
  scanf("%lld%lld%lld%lld", &N, &M, &K, &Q);
  rep(i, M) {
    scanf("%lld%lld%lld", &A[i], &B[i], &C[i]);
    A[i]--;
    B[i]--;
    G[A[i]].pb({B[i], C[i]});
    G[B[i]].pb({A[i], C[i]});
  }

  fill_n(dist, N, INF);
  priority_queue<pint, vector<pint>, greater<pint>> que;
  rep(i, K) {
    int v;
    scanf("%lld", &v);
    v--;
    dist[v] = 0;
    que.push({0, v});
  }
  while (que.size()) {
    int c, v;
    tie(c, v) = que.top();
    que.pop();
    if (dist[v] < c)
      continue;
    for (auto &e : G[v]) {
      if (dist[e.fi] <= c + e.se)
        continue;
      dist[e.fi] = c + e.se;
      que.push({dist[e.fi], e.fi});
    }
  }

  // cout<<"-----------------"<<endl;
  // rep(i,N)cout<<dist[i]<<" ";cout<<endl;

  LinkCutTree lct(N);
  rep(i, N) lct.nodes[i].val = lct.nodes[i].agg = dist[i];
  vector<pint> es;
  rep(i, M) es.pb({min(dist[A[i]], dist[B[i]]), i});
  sort(all(es));
  reverse(all(es));
  rep(i, es.size()) {
    int j = es[i].se;
    if (lct.findRoot(A[j]) == lct.findRoot(B[j]))
      continue;
    lct.evert(A[j]);
    lct.link(A[j], B[j]);
  }

  /*
  cout<<endl;
  rep(i,N)cout<<lct.nodes[i].isRoot()<<" ";cout<<endl;
  rep(i,N){
      cout<<i+1<<" ";
      if(lct.nodes[i].pp)cout<<lct.nodes[i].pp-lct.nodes+1<<endl;
      else cout<<-1<<endl;
  }

  cout<<"---------"<<endl;
*/

  while (Q--) {
    int a, b;
    scanf("%lld%lld", &a, &b);
    a--;
    b--;
    printf("%lld\\n", lct.query(a, b));
  }
  return 0;
}

Error: MLE

Fixed submission:

#include <bits/stdc++.h>
using namespace std;

#define int long long
typedef pair<int, int> pint;
typedef vector<int> vint;
typedef vector<pint> vpint;
#define pb push_back
#define mp make_pair
#define fi first
#define se second
#define all(v) (v).begin(), (v).end()
#define rep(i, n) for (int i = 0; i < (n); i++)
#define reps(i, f, n) for (int i = (f); i < (n); i++)
#define each(it, v)                                                            \\
  for (__typeof((v).begin()) it = (v).begin(); it != (v).end(); it++)
template <class T, class U> inline void chmin(T &t, U f) {
  if (t > f)
    t = f;
}
template <class T, class U> inline void chmax(T &t, U f) {
  if (t < f)
    t = f;
}

const int INF = 1001001001;
int N, M, K, Q;
vpint G[100000];
int dist[100000];

int par[100000];
set<pint> querys[100000];

int find(int x) { return x == par[x] ? x : par[x] = find(par[x]); }

int ans[100000];

signed main() {
  scanf("%lld%lld%lld%lld", &N, &M, &K, &Q);
  rep(i, M) {
    int a, b, c;
    scanf("%lld%lld%lld", &a, &b, &c);
    a--;
    b--;
    G[a].pb(pint(b, c));
    G[b].pb(pint(a, c));
  }

  fill_n(dist, N, INF);
  priority_queue<pint, vector<pint>, greater<pint>> que;
  rep(i, K) {
    int v;
    scanf("%lld", &v);
    v--;
    dist[v] = 0;
    que.push(pint(0, v));
  }

  while (que.size()) {
    int c, v;
    tie(c, v) = que.top();
    que.pop();
    if (dist[v] < c)
      continue;
    for (auto p : G[v]) {
      if (dist[p.fi] <= c + p.se)
        continue;
      dist[p.fi] = c + p.se;
      que.push(pint(dist[p.fi], p.fi));
    }
  }

  vector<tuple<int, int, int>> edges;

  rep(i, N) {
    par[i] = i;
    for (auto p : G[i]) {
      if (i > p.fi)
        continue;
      edges.pb(make_tuple(min(dist[i], dist[p.fi]), i, p.fi));
    }
  }

  rep(i, Q) {
    int a, b;
    scanf("%lld%lld", &a, &b);
    a--;
    b--;
    querys[a].insert(pint(i, a + b));
    querys[b].insert(pint(i, a + b));
  }

  sort(all(edges));
  reverse(all(edges));

  rep(i, edges.size()) {
    int a, b, c;
    tie(c, a, b) = edges[i];
    a = find(a);
    b = find(b);
    if (a == b)
      continue;
    if (querys[a].size() < querys[b].size())
      swap(querys[a], querys[b]);
    each(it, querys[b]) {
      if (querys[a].find(*it) != querys[a].end()) {
        ans[it->fi] = c;
        querys[a].erase(*it);
      } else {
        querys[a].insert(*it);
      }
    }
    par[b] = a;
  }

  rep(i, Q) printf("%lld\\n", ans[i]);
  return 0;
}