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

#include <cstdio>
#include <forward_list>
#include <iostream>
#include <map>
#include <unordered_map>
#include <utility>
#include <vector>

#define MAXN 100000

using namespace std;

int pre[MAXN] = {-1};
int st[MAXN];

vector<pair<int, int>> vp;
vector<forward_list<int>> query;
map<pair<int, int>, int> mans;

struct pair_hash {
  template <class T1, class T2> size_t operator()(const pair<T1, T2> &p) const {
    auto h1 = hash<T1>{}(p.first);
    auto h2 = hash<T2>{}(p.second);
    return h1 + h2;
  }
};

unordered_map<pair<int, int>, int, pair_hash> seek;

void swap(int &i, int &j) {
  int t = i;
  i = j;
  j = t;
}

class Edge {
public:
  int s;
  int t;
  Edge(int si, int ti) : s(si), t(ti) { ; }
};

class Graph {
public:
  int V;
  vector<forward_list<int>> adj;
  Graph(int v) : V(v) {
    adj.resize(v);
    query.resize(v);
    for (int i = 0; i < V; i++) {
      st[i] = i;
      pre[i] = -1;
    }
  }
  void addEdge(int i, int j) { adj[i].push_front(j); }
  void tarjanR(Edge e);
};

int root(int v) {
  while (st[v] != v)
    v = st[v];
  return v;
}

void Graph::tarjanR(Edge e) {
  int t = e.t;
  int s = e.s;
  pre[t] = 0;

  for (auto a = adj[t].begin(); a != adj[t].end(); ++a) {
    int v = *a;
    if (pre[v] == -1) {
      tarjanR(Edge(t, v));
    }
  }
  for (auto k = query[t].begin(); k != query[t].end(); ++k) {
    int mi = *k, ma = t;
    if (mi > ma)
      swap(mi, ma);
    pair<int, int> p = make_pair(mi, ma);
    if (pre[*k] != -1 && seek.find(p) != seek.end() && seek[p] == -1) {
      seek[p] = root(*k);
    }
  }
  st[t] = s;
}

int main() {
  int V, j, q, tt;
  scanf("%d", &V);
  Graph G(V);
  for (int i = 0; i < V; i++) {
    scanf("%d", &j);
    for (int k = 0; k < j; k++) {
      scanf("%d", &tt);
      G.addEdge(i, tt);
    }
  }

  int s, t;

  scanf("%d", &q);
  for (int i = 0; i < q; i++) {
    scanf("%d %d", &s, &t);
    if (s > t) {
      swap(s, t);
    }
    vp.push_back(make_pair(s, t));
    seek[make_pair(s, t)] = -1;
    query[s].push_front(t);
    query[t].push_front(s);
  }

  G.tarjanR(Edge(0, 0));

  for (int i = 0; i < q; i++) {
    printf("%d\\n", seek[vp[i]]);
  }

  return 0;
}


Error: TLE

Fixed submission:

#include <cstdio>
#include <forward_list>
#include <iostream>
#include <map>
#include <unordered_map>
#include <utility>
#include <vector>

#define MAXN 100000

using namespace std;

int pre[MAXN] = {-1};
int st[MAXN];

vector<pair<int, int>> vp;
map<pair<int, int>, int> mans;

struct pair_hash {
  template <class T1, class T2> size_t operator()(const pair<T1, T2> &p) const {
    auto h1 = hash<T1>{}(p.first);
    auto h2 = hash<T2>{}(p.second);
    return h1 ^ h2;
  }
};

unordered_map<pair<int, int>, int, pair_hash> seek;

void swap(int &i, int &j) {
  int t = i;
  i = j;
  j = t;
}

class Edge {
public:
  int s;
  int t;
  Edge(int si, int ti) : s(si), t(ti) { ; }
};

class Graph {
public:
  int V;
  vector<forward_list<int>> adj;
  Graph(int v) : V(v) {
    adj.resize(v);
    for (int i = 0; i < V; i++) {
      st[i] = i;
      pre[i] = -1;
    }
  }
  void addEdge(int i, int j) { adj[i].push_front(j); }
  void tarjanR(Edge e);
};

int root(int v) {
  while (st[v] != v)
    v = st[v];
  return v;
}

void Graph::tarjanR(Edge e) {
  int t = e.t;
  int s = e.s;
  pre[t] = 0;

  for (auto a = adj[t].begin(); a != adj[t].end(); ++a) {
    int v = *a;
    if (pre[v] == -1) {
      tarjanR(Edge(t, v));
    }
  }
  for (int i = 0; i < V; i++) {
    int mi = i, ma = t;
    if (mi > ma)
      swap(mi, ma);
    pair<int, int> p = make_pair(mi, ma);
    if (pre[i] != -1 && seek.find(p) != seek.end() && seek[p] == -1) {
      seek[p] = root(i);
    }
  }
  st[t] = s;
}

int main() {
  int V, j, q, tt;
  scanf("%d", &V);
  Graph G(V);
  for (int i = 0; i < V; i++) {
    scanf("%d", &j);
    for (int k = 0; k < j; k++) {
      scanf("%d", &tt);
      G.addEdge(i, tt);
    }
  }

  int s, t;

  scanf("%d", &q);
  for (int i = 0; i < q; i++) {
    scanf("%d %d", &s, &t);
    if (s > t) {
      swap(s, t);
    }
    vp.push_back(make_pair(s, t));
    seek[make_pair(s, t)] = -1;
  }

  G.tarjanR(Edge(0, 0));

  for (int i = 0; i < q; i++) {
    printf("%d\\n", seek[vp[i]]);
  }

  return 0;
}