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

#include <algorithm>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <queue>

#define pi pair<ll, int>
#define fi first
#define se second
#define mp make_pair

using namespace std;

#define ll long long

const int N = (int)2e5 + 10;

int gi() {
  char c = getchar();
  int ret = 0;
  while (!isdigit(c))
    c = getchar();
  while (isdigit(c)) {
    ret = ret * 10 + c - '0';
    c = getchar();
  }
  return ret;
}

int n, m;
int edge[N][2];
bool tree[N];
int cnt = 1, lst[N], nxt[N * 2], to[N * 2];

void add(int u, int v) {
  nxt[++cnt] = lst[u];
  lst[u] = cnt;
  to[cnt] = v;
  nxt[++cnt] = lst[v];
  lst[v] = cnt;
  to[cnt] = u;
}

bool vis[N];
int indx, id[N], fa[N][20], dep[N];
void dfs(int u) {
  vis[u] = 1;
  id[u] = ++indx;
  for (int j = lst[u]; j; j = nxt[j]) {
    int v = to[j];
    if (vis[v])
      continue;
    fa[v][0] = u;
    dep[v] = dep[u] + 1;
    dfs(v);
    tree[j >> 1] = 1;
  }
}
void PreLca() {
  for (int j = 1; j < 20; j++)
    for (int i = 1; i <= n; i++)
      fa[i][j] = fa[fa[i][j - 1]][j - 1];
}
int lca(int u, int v) {
  if (dep[u] < dep[v])
    swap(u, v);
  for (int k = dep[u] - dep[v], j = 0; k; j++, k >>= 1)
    if (k & 1)
      u = fa[u][j];
  if (u == v)
    return u;
  for (int j = 19; j >= 0; j--)
    if (fa[u][j] != fa[v][j])
      u = fa[u][j], v = fa[v][j];
  return fa[u][0];
}

int mt, nt, E[N][2], nd[N], vfa[N];
bool key[N];
bool cmp(int i, int j) { return id[i] < id[j]; }

int top, stk[N];
void vadd(int u, int v) { vfa[v] = u; }
void BuildVT() {
  sort(nd + 1, nd + nt + 1, cmp);

  int _nt = nt;
  for (int i = 1; i <= nt; i++) {
    int x = nd[i];
    if (!top) {
      stk[++top] = x;
      continue;
    }

    int plca = lca(stk[top], x);
    while (dep[stk[top - 1]] > dep[plca] && top > 1) {
      vadd(stk[top - 1], stk[top]);
      top--;
    }
    if (dep[plca] < dep[stk[top]]) {
      vadd(plca, stk[top]);
      top--;
    }
    if (!top || dep[stk[top]] < dep[plca])
      stk[++top] = plca;
    stk[++top] = x;
    if (!key[plca]) {
      key[plca] = 1;
      nd[++_nt] = plca;
    }
  }
  while (top > 1) {
    vadd(stk[top - 1], stk[top]);
    top--;
  }

  nt = _nt;
}

bool mark[N];
int deg[N];
int _cnt, _tim, _lst[N], _nxt[N], _to[N], _flag[N], _vis[N];
void _add(int u, int v) {
  deg[u]++;
  deg[v]++;
  if (_flag[u] != _tim)
    _lst[u] = 0, _flag[u] = _tim;
  if (_flag[v] != _tim)
    _lst[v] = 0, _flag[v] = _tim;
  _nxt[++_cnt] = _lst[u];
  _lst[u] = _cnt;
  _to[_cnt] = v;
  _nxt[++_cnt] = _lst[v];
  _lst[v] = _cnt;
  _to[_cnt] = u;
}

void _dfs(int u) {
  if (_vis[u] == _tim)
    return;
  _vis[u] = _tim;

  for (int j = _lst[u]; j; j = _nxt[j]) {
    int v = _to[j];

    _dfs(v);
  }
}

void work() {
  int ans = 0;

  for (int s = 1; s < (1 << mt); s++) {
    for (int i = 1; i <= nt; i++)
      mark[nd[i]] = 0, deg[nd[i]] = 0;
    _cnt = 0;
    _tim++;

    for (int i = 1; i <= mt; i++)
      if ((s >> (i - 1)) & 1) {
        for (int p = E[i][0]; p; p = vfa[p])
          mark[p] ^= 1;
        for (int p = E[i][1]; p; p = vfa[p])
          mark[p] ^= 1;
      }

    for (int i = 1; i <= mt; i++)
      if ((s >> (i - 1)) & 1) {
        _add(E[i][0], E[i][1]);
      }

    for (int i = 1; i <= nt; i++)
      if (mark[nd[i]] && vfa[nd[i]]) {
        _add(nd[i], vfa[nd[i]]);
      }

    bool ok = 1;
    for (int i = 1; i <= nt && ok; i++)
      if (deg[nd[i]] && deg[nd[i]] != 2)
        ok = 0;

    for (int i = 1; i <= nt && ok; i++)
      if (deg[nd[i]]) {
        _dfs(nd[i]);
        break;
      }

    for (int i = 1; i <= nt && ok; i++)
      if (deg[nd[i]] && _vis[nd[i]] != _tim)
        ok = 0;

    if (ok)
      ans++;
  }
  printf("%d\\n", ans);
}

int main() {

  n = gi();
  m = gi();
  for (int i = 1; i <= m; i++) {
    edge[i][0] = gi();
    edge[i][1] = gi();
    add(edge[i][0], edge[i][1]);
  }

  dfs(1);
  PreLca();

  for (int i = 1; i <= m; i++)
    if (!tree[i]) {
      ++mt;
      E[mt][0] = edge[i][0], E[mt][1] = edge[i][1];
      if (!key[edge[i][0]])
        key[edge[i][0]] = 1, nd[++nt] = edge[i][0];
      if (!key[edge[i][1]])
        key[edge[i][1]] = 1, nd[++nt] = edge[i][1];
      // printf("%d %d\\n", E[mt][0], E[mt][1]);
    }

  BuildVT();
  work();

  return 0;
}


Error: TLE

Fixed submission:

#include <cstdio>
#include <iostream>
#include <vector>
using namespace std;

int fa[100005], p[17], q[17], pn, ans, area[100005], u, v, n, m;
vector<int> E[100005], G[100005];
int vis[100005], im[100005];

int find_set(int *fa, int x) {
  return x == fa[x] ? x : fa[x] = find_set(fa, fa[x]);
}

void cnt(int x) {
  if (vis[x])
    return;
  vis[x] = true;
  for (int &j : G[x])
    if (!vis[j]) {
      cnt(j);
      if (j == v)
        ++ans;
    }
  vis[x] = false;
}

void dfs(int r, int x, int f) {
  for (int &j : E[x])
    if (j != f)
      if (!im[j])
        area[j] = r, dfs(r, j, x);
      else
        area[j] = j, dfs(j, j, x);
}

int main() {
  scanf("%d%d", &n, &m);
  for (int i = 1; i <= n; i++)
    fa[i] = i;
  for (int i = 1, a, b, c; i <= m; i++) {
    scanf("%d%d", &a, &b);
    if (find_set(fa, a) != find_set(fa, b))
      fa[find_set(fa, a)] = find_set(fa, b), E[a].push_back(b),
                      E[b].push_back(a);
    else
      p[++pn] = a, q[pn] = b, im[a] = im[b] = true;
  }
  for (int i = 1; i <= n; i++)
    if (E[i].size() > 2)
      im[i] = true;
  im[1] = true;
  area[1] = 1, dfs(1, 1, 0);
  for (int i = 1; i <= n; i++)
    for (int &j : E[i])
      if (area[i] != area[j])
        G[area[i]].push_back(area[j]);
  for (int i = 1; i <= pn; i++) {
    G[p[i]].push_back(q[i]), G[q[i]].push_back(p[i]);
    u = p[i], v = q[i];
    cnt(u);
    --ans;
  }
  cout << ans << endl;
  return 0;
}