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

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<int, int> P;
typedef vector<vector<int>> Graph;
int n[2], m[2];
map<string, int> mp;
vector<int> vp;
int cnt = 1;

vector<Graph> Forest_to_Trees(Graph &G) {
  vector<int> num(n[0], -1);
  vector<Graph> tree;
  for (int i = 0; i < n[0]; i++) {
    if (num[i] == -1) {
      Graph gra(1);
      queue<int> q;
      q.push(i);
      int cur = 0;
      num[i] = 0;
      while (q.size()) {
        int v = q.front();
        q.pop();
        for (int j = 0; j < G[v].size(); j++) {
          int nv = G[v][j];
          if (num[nv] == -1) {
            num[nv] = ++cur;
            gra.push_back(vector<int>());
            gra[num[v]].push_back(num[nv]);
            gra[num[nv]].push_back(num[v]);
            q.push(nv);
          }
        }
      }
      tree.push_back(gra);
    }
  }
  return tree;
}

int calc2(Graph &G2, int v, int parent) {
  if (G2[v].size() == 0)
    return 1;
  if (G2[v].size() == 1 && parent != -1)
    return 1;
  vector<string> s;
  for (int i = 0; i < (int)G2[v].size(); i++) {
    int nv = G2[v][i];
    if (parent == nv)
      continue;
    int val = calc2(G2, nv, v);
    s.push_back(to_string(val));
  }
  sort(s.begin(), s.end());
  string str = "";
  for (int i = 0; i < s.size(); i++) {
    str += s[i];
  }
  if (!mp.count(str))
    mp.insert(map<string, int>::value_type(str, ++cnt));
  return mp[str];
}

void dfs2(Graph &G2, int v, vector<int> &dist) {
  if (dist[v] == -1)
    dist[v] = 0;
  for (int i = 0; i < G2[v].size(); i++) {
    if (dist[G2[v][i]] == -1) {
      dist[G2[v][i]] = dist[v] + 1;
      dfs2(G2, G2[v][i], dist);
    }
  }
}

vector<int> getCenter(Graph &G) {
  int nn = G.size();
  vector<int> dist(nn, -1);
  vector<int> dist2(nn, -1);
  vector<int> dist3(nn, -1);
  dfs2(G, 0, dist);
  int maxi = -1;
  int tgt = 0;
  for (int i = 0; i < nn; i++) {
    if (dist[i] > maxi) {
      maxi = dist[i];
      tgt = i;
    }
  }
  dfs2(G, tgt, dist2);
  maxi = -1;
  for (int i = 0; i < nn; i++) {
    if (dist2[i] > maxi) {
      maxi = dist2[i];
      tgt = i;
    }
  }
  dfs2(G, tgt, dist3);
  vector<int> res;
  for (int i = 0; i < nn; i++) {
    if (maxi % 2 == 0) {
      if (dist2[i] == maxi / 2 && dist3[i] == maxi / 2)
        res.push_back(i);
    } else {
      if (dist2[i] == (maxi + 1) / 2 && dist3[i] == maxi / 2)
        res.push_back(i);
      if (dist2[i] == maxi / 2 && dist3[i] == (maxi + 1) / 2)
        res.push_back(i);
    }
  }
  return res;
}

int main(void) {
  Graph g2;
  scanf("%d%d", &n[0], &m[0]);
  Graph G(n[0]);
  for (int i = 0; i < m[0]; i++) {
    int f, t;
    scanf("%d%d", &f, &t);
    f--;
    t--;
    G[f].push_back(t);
    G[t].push_back(f);
  }
  vector<Graph> tree = Forest_to_Trees(G);
  scanf("%d", &n[1]);
  m[1] = n[1] - 1;
  for (int i = 0; i < n[1]; i++) {
    g2.push_back(vector<int>());
  }
  for (int i = 0; i < m[1]; i++) {
    int f, t;
    scanf("%d%d", &f, &t);
    f--;
    t--;
    g2[f].push_back(t);
    g2[t].push_back(f);
  }
  vector<int> root[2];
  root[1] = getCenter(g2);
  mp["0"] = 1;
  for (int i = 0; i < root[1].size(); i++) {
    vp.push_back(calc2(g2, root[1][i], -1));
  }
  int res = 0;
  for (int i = 0; i < tree.size(); i++) {
    if (tree[i].size() != n[1])
      continue;
    root[0].clear();
    root[0] = getCenter(tree[i]);
    bool flag = false;
    for (int j = 0; j < root[0].size(); j++) {
      if (flag)
        break;
      int s1 = calc2(tree[i], root[0][j], -1);
      for (int k = 0; k < vp.size(); k++) {
        if (s1 == vp[k])
          flag = true;
      }
    }
    if (flag)
      res++;
  }
  printf("%d\\n", res);
  return 0;
}

Error: TLE

Fixed submission:

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<int, int> P;
typedef vector<vector<int>> Graph;
int n[2], m[2];
int dist[400001];
int dist2[400001];
map<string, int> mp;
vector<int> vp;
int cnt = 1;

vector<Graph> Forest_to_Trees(Graph &G) {
  vector<int> num(n[0], -1);
  vector<Graph> tree;
  for (int i = 0; i < n[0]; i++) {
    if (num[i] == -1) {
      Graph gra(1);
      queue<int> q;
      q.push(i);
      int cur = 0;
      num[i] = 0;
      while (q.size()) {
        int v = q.front();
        q.pop();
        for (int j = 0; j < G[v].size(); j++) {
          int nv = G[v][j];
          if (num[nv] == -1) {
            num[nv] = ++cur;
            gra.push_back(vector<int>());
            gra[num[v]].push_back(num[nv]);
            gra[num[nv]].push_back(num[v]);
            q.push(nv);
          }
        }
      }
      tree.push_back(gra);
    }
  }
  return tree;
}

int calc2(Graph &G2, int v, int parent) {
  if (G2[v].size() == 0)
    return 1;
  if (G2[v].size() == 1 && parent != -1)
    return 1;
  vector<string> s;
  for (int i = 0; i < (int)G2[v].size(); i++) {
    int nv = G2[v][i];
    if (parent == nv)
      continue;
    int val = calc2(G2, nv, v);
    s.push_back(to_string(val));
  }
  sort(s.begin(), s.end());
  string str = "";
  for (int i = 0; i < s.size(); i++) {
    str += s[i];
  }
  if (!mp.count(str))
    mp.insert(map<string, int>::value_type(str, ++cnt));
  return mp[str];
}

void dfs2(Graph &G2, int v) {
  if (dist[v] == -1)
    dist[v] = 0;
  for (int i = 0; i < G2[v].size(); i++) {
    if (dist[G2[v][i]] == -1) {
      dist[G2[v][i]] = dist[v] + 1;
      dfs2(G2, G2[v][i]);
    }
  }
}

int main(void) {
  Graph g2;
  scanf("%d%d", &n[0], &m[0]);
  Graph G(n[0]);
  for (int i = 0; i < m[0]; i++) {
    int f, t;
    scanf("%d%d", &f, &t);
    f--;
    t--;
    G[f].push_back(t);
    G[t].push_back(f);
  }
  vector<Graph> tree = Forest_to_Trees(G);
  scanf("%d", &n[1]);
  m[1] = n[1] - 1;
  for (int i = 0; i < n[1]; i++) {
    g2.push_back(vector<int>());
  }
  for (int i = 0; i < m[1]; i++) {
    int f, t;
    scanf("%d%d", &f, &t);
    f--;
    t--;
    g2[f].push_back(t);
    g2[t].push_back(f);
  }
  vector<int> root[2];
  memset(dist, -1, sizeof(dist));
  dfs2(g2, 0);
  int maxi = -1;
  int tgt = 0;
  for (int i = 0; i < n[1]; i++) {
    if (dist[i] > maxi) {
      maxi = dist[i];
      tgt = i;
    }
  }
  memset(dist, -1, sizeof(dist));
  dfs2(g2, tgt);
  maxi = -1;
  for (int i = 0; i < n[1]; i++) {
    if (dist[i] > maxi) {
      maxi = dist[i];
      tgt = i;
    }
    dist2[i] = dist[i];
  }
  int maxi2 = maxi;

  memset(dist, -1, sizeof(dist));
  dfs2(g2, tgt);
  for (int i = 0; i < n[1]; i++) {
    if (maxi % 2 == 0) {
      if (dist[i] == maxi / 2 && dist2[i] == maxi / 2)
        root[1].push_back(i);
    } else {
      if (dist[i] == (maxi + 1) / 2 && dist2[i] == maxi / 2)
        root[1].push_back(i);
      if (dist[i] == maxi / 2 && dist2[i] == (maxi + 1) / 2)
        root[1].push_back(i);
    }
  }
  if (root[1].size() > 2)
    return 0;
  mp["0"] = 1;
  for (int i = 0; i < root[1].size(); i++) {
    vp.push_back(calc2(g2, root[1][i], -1));
  }
  int res = 0;
  for (int i = 0; i < tree.size(); i++) {
    if (tree[i].size() != n[1])
      continue;
    root[0].clear();
    memset(dist, -1, sizeof(dist));
    dfs2(tree[i], 0);
    maxi = -1;
    tgt = 0;
    for (int j = 0; j < n[1]; j++) {
      if (dist[j] > maxi) {
        maxi = dist[j];
        tgt = j;
      }
    }
    memset(dist, -1, sizeof(dist));
    dfs2(tree[i], tgt);
    maxi = -1;
    for (int j = 0; j < n[1]; j++) {
      if (dist[j] > maxi) {
        maxi = dist[j];
        tgt = j;
      }
      dist2[j] = dist[j];
    }
    if (maxi != maxi2)
      continue;
    memset(dist, -1, sizeof(dist));
    dfs2(tree[i], tgt);
    for (int j = 0; j < n[1]; j++) {
      if (maxi % 2 == 0) {
        if (dist[j] == maxi / 2 && dist2[j] == maxi / 2)
          root[0].push_back(j);
      } else {
        if (dist[j] == (maxi + 1) / 2 && dist2[j] == maxi / 2)
          root[0].push_back(j);
        if (dist[j] == maxi / 2 && dist2[j] == (maxi + 1) / 2)
          root[0].push_back(j);
      }
    }
    bool flag = false;
    for (int j = 0; j < root[0].size(); j++) {
      if (flag)
        break;
      int s1 = calc2(tree[i], root[0][j], -1);
      for (int k = 0; k < vp.size(); k++) {
        if (s1 == vp[k])
          flag = true;
      }
    }
    if (flag)
      res++;
  }
  printf("%d\\n", res);
  return 0;
}