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

#include <bits/stdc++.h>
using namespace std;
using Int = long long;
// BEGIN CUT HERE
template <typename T, bool directed> struct Dinic {
  struct edge {
    int to;
    T cap;
    int rev;
    edge() {}
    edge(int to, T cap, int rev) : to(to), cap(cap), rev(rev) {}
  };

  vector<vector<edge>> G;
  vector<int> level, iter;

  Dinic() {}
  Dinic(int n) : G(n), level(n), iter(n) {}

  int add_edge(int from, int to, T cap) {
    G[from].emplace_back(to, cap, G[to].size());
    G[to].emplace_back(from, directed ? 0 : cap, G[from].size() - 1);
    return G[to].back().rev;
  }

  void bfs(int s) {
    fill(level.begin(), level.end(), -1);
    queue<int> que;
    level[s] = 0;
    que.emplace(s);
    while (!que.empty()) {
      int v = que.front();
      que.pop();
      for (int i = 0; i < (int)G[v].size(); i++) {
        edge &e = G[v][i];
        if (e.cap > 0 && level[e.to] < 0) {
          level[e.to] = level[v] + 1;
          que.emplace(e.to);
        }
      }
    }
  }

  T dfs(int v, int t, T f) {
    if (v == t)
      return f;
    for (int &i = iter[v]; i < (int)G[v].size(); i++) {
      edge &e = G[v][i];
      if (e.cap > 0 && level[v] < level[e.to]) {
        T d = dfs(e.to, t, min(f, e.cap));
        if (d == 0)
          continue;
        e.cap -= d;
        G[e.to][e.rev].cap += d;
        return d;
      }
    }
    return 0;
  }

  T flow(int s, int t, T lim) {
    T fl = 0;
    while (1) {
      bfs(s);
      if (level[t] < 0 || lim == 0)
        break;
      fill(iter.begin(), iter.end(), 0);

      while (1) {
        T f = dfs(s, t, lim);
        if (f == 0)
          break;
        fl += f;
        lim -= f;
      }
    }
    return fl;
  }

  T flow(int s, int t) { return flow(s, t, numeric_limits<T>::max() / 2); }

  T cut(int s, int t, int x, int a) {
    static_assert(directed, "must be directed");
    auto &e = G[x][a];
    int y = e.to;
    T ce = e.cap, cr = G[y][e.rev].cap;
    if (cr == 0)
      return 0;
    e.cap = G[y][e.rev].cap = 0;
    T cap = cr - flow(x, y, cr);
    if (x != s && cap != 0)
      flow(x, s, cap);
    if (t != y && cap != 0)
      flow(t, y, cap);
    e.cap = ce + cr;
    return cap;
  }
};
// END CUT HERE

template <typename T> vector<T> compress(vector<T> v) {
  sort(v.begin(), v.end());
  v.erase(unique(v.begin(), v.end()), v.end());
  return v;
}

template <typename T> map<T, int> dict(const vector<T> &v) {
  map<T, int> res;
  for (int i = 0; i < (int)v.size(); i++)
    res[v[i]] = i;
  return res;
}
// INSERT ABOVE HERE
signed GRL_6_A() {
  cin.tie(0);
  ios::sync_with_stdio(0);
  int V, E;
  cin >> V >> E;
  Dinic<int, true> dinic(V);
  for (int i = 0; i < E; i++) {
    int u, v, c;
    cin >> u >> v >> c;
    dinic.add_edge(u, v, c);
  }
  cout << dinic.flow(0, V - 1) << endl;
  return 0;
}

/*
  verified on 2019/06/10
  http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=GRL_6_A&lang=jp
*/

signed SPOJ_FASTFLOW() {
  cin.tie(0);
  ios::sync_with_stdio(0);
  Int n, m;
  cin >> n >> m;
  Dinic<Int, false> G(n);
  for (Int i = 0; i < m; i++) {
    Int a, b, c;
    cin >> a >> b >> c;
    if (a == b)
      continue;
    a--;
    b--;
    G.add_edge(a, b, c);
  }
  cout << G.flow(0, n - 1) << endl;
  return 0;
}
/*
  verified on 2019/06/10
  https://www.spoj.com/problems/FASTFLOW/
*/

signed SPOJ_BANKROB() {
  cin.tie(0);
  ios::sync_with_stdio(0);

  int n, m, s, t;
  cin >> n >> m >> s >> t;
  s--;
  t--;
  const int INF = 5050;
  Dinic<int, true> G(n * 2);
  for (int i = 0; i < m; i++) {
    int x, y;
    cin >> x >> y;
    x--;
    y--;
    G.add_edge(n + x, y, INF);
    G.add_edge(n + y, x, INF);
  }

  for (int i = 0; i < n; i++)
    G.add_edge(i, n + i, 1);

  cout << G.flow(n + s, t) << endl;
  return 0;
}
/*
  verified on 2019/06/10
  https://www.spoj.com/problems/BANKROB/
*/

signed AOJ_1599() {
  cin.tie(0);
  ios::sync_with_stdio(0);

  int n;
  cin >> n;
  vector<string> es(n);
  for (int i = 0; i < n; i++)
    cin >> es[i];

  const int L = 5;
  vector<string> vs;
  for (string &s : es) {
    for (char &c : s) {
      if (isdigit(c))
        c = c - '0';
      else
        c = c - 'a' + 10;
    }
    for (int i = 0; i < L; i++) {
      if (s[i] & 1)
        continue;
      s[i] = (s[i] + 1) % 16;
      vs.emplace_back(s);
      s[i] = (s[i] + 15) % 16;

      s[i] = (s[i] + 15) % 16;
      vs.emplace_back(s);
      s[i] = (s[i] + 1) % 16;
    }
  }
  es = compress(es);
  vs = compress(vs);
  auto vd = dict(vs);

  auto restore = [](string s) {
    for (char &c : s) {
      if (c >= 10)
        c = 'a' + (c - 10);
      else
        c = '0' + c;
    }
    return s;
  };

  int m = vd.size();
  Dinic<int, true> G(m + 2);
  int S = m, T = m + 1;

  vector<int> used(m, 0);
  using P = pair<int, int>;
  map<string, P> mp;

  for (string &s : es) {
    for (int i = 0; i < L; i++) {
      if (s[i] & 1)
        continue;

      s[i] = (s[i] + 1) % 16;
      int x = vd[s];
      s[i] = (s[i] + 15) % 16;

      s[i] = (s[i] + 15) % 16;
      int y = vd[s];
      s[i] = (s[i] + 1) % 16;

      int sum = 0;
      for (char c : vs[x])
        sum += c / 2;
      if (sum & 1)
        swap(x, y);

      mp[s] = P(x, G.add_edge(x, y, 1));

      if (!used[x]) {
        mp[vs[x]] = P(S, G.add_edge(S, x, 1));
        used[x] = 1;
      }

      if (!used[y]) {
        mp[vs[y]] = P(y, G.add_edge(y, T, 1));
        used[y] = 1;
      }
    }
  }

  vector<string> as;
  for (auto s : es)
    as.emplace_back(s);
  for (auto s : vs)
    as.emplace_back(s);
  sort(as.begin(), as.end());

  cout << G.flow(S, T) << "\\n";
  for (auto s : as) {
    int x = mp[s].first;
    int a = mp[s].second;
    if (G.cut(S, T, x, a) == 1) {
      G.G[x][a].cap = 0;
      cout << restore(s) << "\\n";
    }
  }
  cout << flush;
  return 0;
}
/*
  verified on 2019/06/18
  http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=1599
*/

signed main() {
  // GRL_6_A();
  // SPOJ_FASTFLOW();
  // SPOJ_BANKROB();
  AOJ_1599();
  return 0;
}


Error: TLE

Fixed submission:

#include <bits/stdc++.h>
using namespace std;
#define MAX_V 12050
typedef pair<string, bool> B;
typedef pair<int, int> P;
vector<string> v1, v2, ans;
vector<B> v3;
set<string> sv;
map<string, int> m, mv, me;
map<P, int> ok;
void addV(string s) {
  sv.insert(s);
  v1.push_back(s);
  for (int i = 0; i < 5; i++) {
    if ((('0' <= s[i] && s[i] <= '9') && (s[i] - '0') % 2 == 0) ||
        (('a' <= s[i] && s[i] <= 'f') && (s[i] - 'a') % 2 == 0)) {
      if (s[i] == '0') {
        s[i] = 'f';
        v2.push_back(s);
        m[s]++;
        s[i] = '0';
      } else if (s[i] == 'a') {
        s[i] = '9';
        v2.push_back(s);
        m[s]++;
        s[i] = 'a';
      } else {
        s[i]--;
        v2.push_back(s);
        m[s]++;
        s[i]++;
      }
      s[i]++;
      v2.push_back(s);
      m[s]++;
      s[i]--;
    }
  }
}

int V, base, cur, res = 0;
vector<int> G[MAX_V];
int match[MAX_V];
bool used[MAX_V], lr[MAX_V], er[MAX_V], erv[MAX_V], rm[MAX_V], rme[MAX_V];
void add_edge(int u, int v) {
  G[u].push_back(v);
  G[v].push_back(u);
}

bool erV(string s) {
  string s1, s2;
  for (int i = 0; i < 5; i++) {
    if ((('0' <= s[i] && s[i] <= '9') && (s[i] - '0') % 2 == 0) ||
        (('a' <= s[i] && s[i] <= 'f') && (s[i] - 'a') % 2 == 0)) {
      if (s[i] == '0') {
        s[i] = 'f';
        s1 = s;
        s[i] = '0';
      } else if (s[i] == 'a') {
        s[i] = '9';
        s1 = s;
        s[i] = 'a';
      } else {
        s[i]--;
        s1 = s;
        s[i]++;
      }
      s[i]++;
      s2 = s;
      s[i]--;
    }
  }
  if (m[s1] == 1 && m[s2] == 1) {
    er[mv[s1]] = er[mv[s2]] = true;
    ans.push_back(min(s, min(s1, s2)));
    return true;
  }
  return false;
}

void mkG(string s) {
  string s1, s2;
  for (int i = 0; i < 5; i++) {
    if ((('0' <= s[i] && s[i] <= '9') && (s[i] - '0') % 2 == 0) ||
        (('a' <= s[i] && s[i] <= 'f') && (s[i] - 'a') % 2 == 0)) {
      if (s[i] == '0') {
        s[i] = 'f';
        s1 = s;
        s[i] = '0';
      } else if (s[i] == 'a') {
        s[i] = '9';
        s1 = s;
        s[i] = 'a';
      } else {
        s[i]--;
        s1 = s;
        s[i]++;
      }
      s[i]++;
      s2 = s;
      s[i]--;
    }
  }
  ok[P(mv[s1], mv[s2])] = ok[P(mv[s2], mv[s1])] = me[s];
  add_edge(mv[s1], mv[s2]);
}

void addE() {
  memset(er, 0, sizeof(er));
  memset(erv, 0, sizeof(erv));
  for (int i = 0; i < v2.size(); i++)
    mv[v2[i]] = i;
  for (int i = 0; i < v1.size(); i++)
    erv[i] = erV(v1[i]);
  vector<string> nv1(v1);
  v1.clear();
  for (int i = 0; i < nv1.size(); i++)
    if (!erv[i])
      v1.push_back(nv1[i]);
  vector<string> nv2(v2);
  v2.clear();
  for (int i = 0; i < nv2.size(); i++)
    if (!er[i])
      v2.push_back(nv2[i]);
  for (int i = 0; i < v2.size(); i++) {
    mv[v2[i]] = i;
    v3.push_back(B(v2[i], true));
  }
  for (int i = 0; i < v1.size(); i++) {
    me[v1[i]] = i;
    mkG(v1[i]);
    v3.push_back(B(v1[i], false));
  }
  sort(v3.begin(), v3.end());
}

bool dfs(int v) {
  used[v] = true;
  for (int i = 0; i < G[v].size(); i++) {
    int u = G[v][i], w = match[u];
    if (rm[u])
      continue;
    if (rme[ok[P(u, v)]])
      continue;
    if (w < 0 || !used[w] && dfs(w)) {
      match[v] = u;
      match[u] = v;
      return true;
    }
  }
  return false;
}

int bipartite_matching() {
  for (int v = 0; v < V; v++) {
    if (rm[v])
      continue;
    if (match[v] < 0) {
      memset(used, 0, sizeof(used));
      if (dfs(v)) {
        res++;
      }
    }
  }
  return res;
}

bool ch(string s) {
  if (match[mv[s]] < 0)
    return true;
  match[match[mv[s]]] = -1;
  match[mv[s]] = -1;
  res--;
  return false;
}

bool che(string s) {
  string s1, s2;
  for (int i = 0; i < 5; i++) {
    if ((('0' <= s[i] && s[i] <= '9') && (s[i] - '0') % 2 == 0) ||
        (('a' <= s[i] && s[i] <= 'f') && (s[i] - 'a') % 2 == 0)) {
      if (s[i] == '0') {
        s[i] = 'f';
        s1 = s;
        s[i] = '0';
      } else if (s[i] == 'a') {
        s[i] = '9';
        s1 = s;
        s[i] = 'a';
      } else {
        s[i]--;
        s1 = s;
        s[i]++;
      }
      s[i]++;
      s2 = s;
      s[i]--;
    }
  }
  if (mv[s2] == match[mv[s1]] && mv[s1] == match[mv[s2]]) {
    match[mv[s1]] = -1;
    match[mv[s2]] = -1;
    res--;
    return false;
  }
  return true;
}

void addA() {
  memset(rm, 0, sizeof(rm));
  memset(rme, 0, sizeof(rme));
  for (int i = 0; i < v3.size(); i++) {
    // cout << v3[i].first << ":" << base << ":";
    if (v3[i].second) {
      if (ch(v3[i].first))
        continue;
      rm[mv[v3[i].first]] = true;
      cur = bipartite_matching();
      if (base - cur == 1)
        ans.push_back(v3[i].first), base--;
      else
        rm[mv[v3[i].first]] = false;
    } else {
      if (che(v3[i].first))
        continue;
      rme[me[v3[i].first]] = true;
      cur = bipartite_matching();
      if (base - cur == 1)
        ans.push_back(v3[i].first), base--;
      else
        rme[me[v3[i].first]] = false;
    }

    // cout << cur << endl;
  }
}

int main() {
  int n, i, j, k;
  string s;
  cin >> n;
  for (i = 0; i < n; i++) {
    cin >> s;
    addV(s);
  }
  sort(v2.begin(), v2.end());
  v2.erase(unique(v2.begin(), v2.end()), v2.end());
  addE();
  V = v2.size();

  memset(match, -1, sizeof(match));
  base = bipartite_matching();
  // cout << base << endl;
  addA();
  sort(ans.begin(), ans.end());
  cout << ans.size() << endl;
  for (i = 0; i < ans.size(); i++) {
    cout << ans[i] << endl;
  }
  return 0;
}