Problem p00967 (C++) — buggy submission, verdict: Runtime Error

#include <bits/stdc++.h>

typedef long long ll;
const int maxn = 1e5 + 20;
int n, m;
std::set<int> G[maxn], P[maxn];

int fa[maxn];
int getFa(int u) {
  if (fa[u] == u)
    return u;
  return fa[u] = getFa(fa[u]);
}

void uniFa(int u, int v) {
  u = getFa(u);
  v = getFa(v);
  fa[u] = v;
}

int epl;

void addEdge(int u, int v) {
  G[u].insert(v);
  G[v].insert(u);
}
void delEdge(int u, int v) {
  G[u].erase(v);
  G[v].erase(u);
}

bool ins[maxn];
int labl, lab[maxn], S[maxn];

std::vector<int> hash(int l, int r) {
  std::vector<int> v;
  int mn = 0, mi = -1;
  for (int i = l; i < r; ++i) {
    if (S[i] > mn) {
      mi = i;
      mn = S[i];
    }
  }
  for (int i = mi; i < r; ++i) {
    v.push_back(S[i]);
  }
  for (int i = l; i < mi; ++i) {
    v.push_back(S[i]);
  }
  return v;
}

std::set<std::vector<int>> loop;

void dfs(int u, int f) {
  lab[u] = labl;
  ins[u] = true;
  S[labl] = u;
  ++labl;

  for (const auto &v : G[u])
    if (v != f) {
      if (ins[v]) {
        loop.insert(hash(lab[v], labl));
      } else {
        dfs(v, u);
      }
    }

  ins[u] = false;
  --labl;
}

int main() {
  scanf("%d%d", &n, &m);
  if (n <= 1 || m <= n - 1) {
    puts("0");
    return 0;
  }
  if (m == n) {
    puts("1");
    return 0;
  }
  for (int i = 0, u, v; i < m; ++i) {
    scanf("%d%d", &u, &v);
    addEdge(u, v);
  }
  for (int i = 1; i <= n; ++i) {
    fa[i] = i;
  }
  std::queue<int> q;
  for (int i = 1; i <= n; ++i) {
    if (G[i].size() == 1)
      q.push(i);
  }
  while (!q.empty()) {
    int u = q.front();
    q.pop();
    // fprintf(stderr, "%d\\n", u);
    int v = *G[u].begin();
    delEdge(u, v);
    if (G[v].size() == 1)
      q.push(v);
  }
  for (int i = 1; i <= n; ++i) {
    if (G[i].size() == 2) {
      auto iter = G[i].begin();
      int u = *iter++, v = *iter++;
      if (G[u].size() == 2 && G[u].find(v) == G[u].end() && G[v].size() == 2 &&
          G[v].find(u) == G[v].end()) {
        delEdge(u, i);
        delEdge(v, i);
        addEdge(u, v);
        // fprintf(stderr, "u, i, v %d %d %d\\n", u, i, v);
      }
    }
  }
  // fprintf(stderr, "aA\\n");
  // for(int i = 1; i <= n; ++i) {
  //     int u = getFa(i);
  //     for(const auto &vp : G[i]) {
  //         int v = getFa(vp);
  //         if(u == v)
  //             continue;
  //         P[u].insert(v);
  //         fprintf(stderr, "%d %d\\n", u, v);
  //     }
  // }
  for (int i = 1; i <= n; ++i) {
    int u = getFa(i);
    if (!G[u].empty()) {
      dfs(u, 0);
      break;
    }
  }
  printf("%d\\n", loop.size() / 2);
  return 0;
}


Error: 0

Fixed submission:

#include <bits/stdc++.h>

using namespace std;

#define PB push_back
#define MEM(n, val) memset(n, val, sizeof(n))
#define FOR(i, j, k) for (int i = j; i <= k; i++)
#define ROF(i, j, k) for (int i = j; i >= k; i--)
#define LL long long
#define F first
#define S second
#define PII pair<int, int>
#define PDD pair<double, double>
#define INF 1999999999
#define MP make_pair
#define LN (node * 2)
#define RN ((node * 2) + 1)
#define MX 100010
#define SF(a) scanf("%d", &a)
#define SFF(a, b) scanf("%d %d", &a, &b)
#define MOD 1000000007

int fx[] = {1, -1, 0, 0};
int fy[] = {0, 0, 1, -1};

int n, m;
vector<int> adjl[100010];
vector<int> diff[25];

/// bool is_con[100010];
/// int st;
LL cycle;
bool kha[100010];
LL tmpcyc;

/**
void func(int u, int par)  {
    FOR(i, 0, diff[u].size() - 1)   {
        int v = diff[u][i];
        if(v == par)    {
            continue;
        }
        if(v < st)    {
            continue;
        }
        if(v == st)    {
            tmpcyc++;
            continue;
        }
        if(kha[v] == 0)    {
            kha[v] = 1;
            func(v, u);
            kha[v] = 0;
        }
    }
}
*/

int ss; /// ss = order.size()
LL dp[18][1 << 18];

LL func(int u, int mask) {
  if (dp[u][mask] != -1) {
    return dp[u][mask];
  }
  int cnt = 0;
  int st = ss + 100;
  FOR(i, 0, ss - 1) {
    if (mask & (1 << i)) {
      st = min(st, i);
      cnt++;
    }
  }
  LL ans = 0;
  FOR(i, 0, diff[u].size() - 1) {
    int v = diff[u][i];
    if (v < st) {
      continue;
    }
    if (v == st) {
      /// tmpcyc++;
      if (cnt > 2) {
        ans++;
      }
      continue;
    }
    if (!(mask & (1 << v))) {
      ans += func(v, mask | (1 << v));
    }
    /**
    if(kha[v] == 0)    {
        kha[v] = 1;
        func(v, u);
        kha[v] = 0;
    }
    */
  }
  return dp[u][mask] = ans;
}

/************************* bcc using tarjan's algo start
 * **************************************/
// bcc = biconnected component
int low[MX];
int dis_t[MX]; // discovery time
int ct;        // time count
// vector<int> arti_p;  //articulation point
int nobcc; // number of biconnected components
stack<PII> stk;

int vis[MX];

vector<PII> tis;
vector<int> order;
map<int, int> mp;

void dfs(int u, int par) {
  int sz = adjl[u].size();
  dis_t[u] = ct;
  low[u] = dis_t[u];
  ct++;
  vis[u] = 1;
  // stk.push(u);
  // int child = 0;
  FOR(i, 0, sz - 1) {
    int v = adjl[u][i];
    if (v == par) {
      // this is used if edge can  be bidirectional
      // low[u] = min(low[u], dis_t[v]);
      continue;
    }
    if (vis[v] == 0) {
      // child++;
      stk.push(MP(u, v));
      dfs(v, u);
      low[u] = min(low[u], low[v]);
      if (low[v] >= dis_t[u]) {
        nobcc++;
        /// cout << "start : \\n";
        tis.clear();
        order.clear();
        mp.clear();
        LL ed_no = 0;
        while (1) {
          PII cc = stk.top();
          stk.pop();
          /// cout << cc.F << " " << cc.S << "\\n";
          ed_no++;
          tis.PB({cc.F, cc.S});
          order.PB(cc.F);
          order.PB(cc.S);
          if ((cc.F == u) && (cc.S == v)) {
            break;
          }
        }

        sort(order.begin(), order.end());
        order.erase(unique(order.begin(), order.end()), order.end());
        FOR(i, 0, (int)order.size() - 1) { mp[order[i]] = i; }
        FOR(i, 0, (int)tis.size() - 1) {
          int u = mp[tis[i].F];
          int v = mp[tis[i].S];
          diff[u].PB(v);
          diff[v].PB(u);
          /// cout << u << " " << v << "\\n";
        }

        if (order.size() > 2) {
          MEM(dp, -1);
          ss = order.size();
          /// tmpcyc = 0;
          FOR(i, 0, ss - 1) { cycle += func(i, (1 << i)); }
        }

        /// cycle += (tmpcyc >> 1LL);

        FOR(i, 0, ss - 1) { diff[i].clear(); }
        /**
        tis.clear();
        order.clear();
        mp.clear();
        */
        /// cout << "end : \\n\\n";
      }
    } else if ((dis_t[v] < dis_t[u]) && (vis[v] == 1)) {
      // if v is in the stack that means we are getting a back edge otherwise
      // cross
      low[u] = min(low[u], dis_t[v]);
      stk.push(MP(v, u));
    }
  }
}

// void bcc(int root)  {
void bcc() {
  ct = 0;
  MEM(vis, 0);
  // arti_p.clear();
  nobcc = 0;
  ///*
  FOR(i, 0, n - 1) {
    if (vis[i]) {
      continue;
    }
    dfs(i, -1);
  }
  //*/

  /*
  int sz = arti_p.size();
  cout << "articulation point : ";
  FOR(i, 0, sz - 1)   {
      cout << arti_p[i] << " ";
  }
  cout << "\\n";
  */
}
/************************* bcc using tarjan's algo end
 * **************************************/

map<PII, int> mymy;
set<PII> sp;
bool ase[100010];
set<int> ss_adjl[100010];

int main() {
  /// std::ios_base::sync_with_stdio(false);
  // freopen("in.txt", "r", stdin);
  // freopen("out1.txt", "w", stdout);
  /// cin >> n >> m;
  SFF(n, m);
  FOR(i, 1, m) {
    int u, v;
    /// cin >> u >> v;
    SFF(u, v);
    /**
    adjl[u].PB(v);
    adjl[v].PB(u);
    */
    ss_adjl[u].insert(v);
    ss_adjl[v].insert(u);
    mymy[{min(u, v), max(u, v)}] = 1;
  }

  /// vector<int> order;
  FOR(i, 1, n) { sp.insert({ss_adjl[i].size(), i}); }
  while (!sp.empty()) {
    // cout << "hi " << (*sp.begin()).F << " " << (*sp.begin()).S << " ";
    if ((*sp.begin()).F > 2) {
      break;
    }
    int k = (*sp.begin()).S;
    auto it = ss_adjl[k].begin();
    int u = *(it);
    it++;
    int v = *(it);
    if (mymy[{min(u, v), max(u, v)}] == 1) {
      order.PB(k);
      ase[k] = 1;
      // cout << "ase\\n";
    } else {
      ss_adjl[u].erase(ss_adjl[u].find(k));
      ss_adjl[v].erase(ss_adjl[v].find(k));

      ss_adjl[u].insert(v);
      ss_adjl[v].insert(u);
      mymy[{min(u, v), max(u, v)}] = 1;
      // cout << u << " " << v << " bad\\n";
    }
    sp.erase(sp.begin());
  }

  for (auto it = sp.begin(); it != sp.end(); it++) {
    order.PB((*it).S);
    ase[(*it).S] = 1;
  }
  FOR(u, 1, n) {
    if (!ase[u]) {
      continue;
    }

    for (auto it = ss_adjl[u].begin(); it != ss_adjl[u].end(); it++) {
      int v = (*it);
      if (ase[v]) {
        adjl[u].PB(v);
        /// adjl[v].PB(u);
      }
    }
  }
  /**
  FOR(u, 1, n)   {
      cout << u << " : ";
      FOR(i, 0, (int)adjl[u].size() - 1)   {
          int v = adjl[u][i];
          cout << v << " ";
      }
      cout << "\\n";
  }
  */
  /**


  */

  /**
  FOR(i, 1, n)   {
      st = i;
      func(i, -1);
  }
  cout << (cycle >> 1) << "\\n";
  */
  cycle = 0;
  bcc();
  /// cout << (cycle >> 1) << "\\n";
  printf("%lld\\n", cycle >> 1LL);
  return 0;
}
/**
8 10
1 2
2 3
3 8
8 7
7 6
6 5
5 4
4 1
3 4
3 5


8 10
1 2
2 3
3 4
4 5
5 6
6 7
7 8
8 1
1 3
5 7


4 6
1 2
1 3
1 4
2 3
2 4
3 4
*/