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

///////////////////////////////////////////////////////////////////////////////

#include <bits/stdc++.h>
#include <sys/time.h>
#include <time.h>
#include <unistd.h>

using namespace std;

///////////////////////////////////////////////////////////////////////////////

#define DEBUG 0

#define pb push_back
#define V vector
#define M unordered_map
#define S static

#define rep(i, n) for (ll i = 0LL; i < n; ++i)
#define srep(i, s, n) for (ll i = s; i < n; ++i)
#define rrep(i, n) for (ll i = n - 1LL; i >= 0LL; --i)
#define ALL(a) (a).begin(), (a).end()
#define RALL(a) (a).rbegin(), (a).rend()
#define CIN(x)                                                                 \\
  do {                                                                         \\
    assert(!cin.eof());                                                        \\
    cin >> x;                                                                  \\
    assert(!cin.fail());                                                       \\
  } while (0);
#if DEBUG
#define debug_print(...) _debug_print(__VA_ARGS__)
#define debug_printf(...) printf(__VA_ARGS__)
#define debug_print_time _debug_print_time
#else // DEBUG
#define debug_print(...)
#define debug_printf(...)
#define debug_print_time
#endif // DEBUG

typedef long long ll;
typedef unsigned long long ull;
typedef tuple<ll, ll> t2;
typedef tuple<ll, ll, ll> t3;
typedef tuple<ll, ll, ll, ll> t4;
typedef tuple<ll, ll, ll, ll, ll> t5;
template <typename T>
using priority_queue_incr = priority_queue<T, V<T>, greater<T>>;

///////////////////////////////////////////////////////////////////////////////

template <typename TT, typename T> T get_m(M<TT, T> &m, TT k, T default_value) {
  if (m.find(k) == m.end())
    return m[k] = default_value;
  return m[k];
}

template <typename TT, typename T> void incr_m(M<TT, T> &m, TT k) {
  if (m.find(k) == m.end())
    m[k] = 0;
  m[k]++;
}

template <typename TT, typename T> void incr_m(map<TT, T> &m, TT k) {
  if (m.find(k) == m.end())
    m[k] = 0;
  m[k]++;
}

void llin(ll &a) { CIN(a); }

void llinl1(V<ll> &v, ll count) {
  for (ll i = 0LL; i < count; ++i) {
    ll a;
    CIN(a);
    v.push_back(a);
  }
}

void llinl2(V<t2> &v, ll count) {
  for (ll i = 0LL; i < count; ++i) {
    ll a, b;
    CIN(a >> b);
    v.push_back(t2(a, b));
  }
}

void llinl3(V<t3> &v, ll count) {
  for (ll i = 0LL; i < count; ++i) {
    ll a, b, c;
    CIN(a >> b >> c);
    v.push_back(t3(a, b, c));
  }
}

void llinl4(V<t4> &v, ll count) {
  for (ll i = 0LL; i < count; ++i) {
    ll a, b, c, d;
    CIN(a >> b >> c >> d);
    v.push_back(t4(a, b, c, d));
  }
}

void llina(V<ll> &v, ll count) { llinl1(v, count); }

template <typename T> void sort(V<T> &v) { sort(v.begin(), v.end()); }

template <typename T> void sort_reverse(V<T> &v) {
  sort(v.begin(), v.end(), greater<T>());
}

template <typename T> void _debug_print(T x) { cout << x << endl; }

void _debug_print(const t2 &x) {
  ll x1 = get<0>(x);
  ll x2 = get<1>(x);
  cout << "-- " << x1 << " -- " << x2 << endl;
}

void _debug_print(const t3 &x) {
  ll x1 = get<0>(x);
  ll x2 = get<1>(x);
  ll x3 = get<2>(x);
  cout << "-- " << x1 << " -- " << x2 << " -- " << x3 << endl;
}

void _debug_print(const t4 &x) {
  ll x1 = get<0>(x);
  ll x2 = get<1>(x);
  ll x3 = get<2>(x);
  ll x4 = get<3>(x);
  cout << "-- " << x1 << " -- " << x2 << " -- " << x3 << " -- " << x4 << endl;
}

template <typename T> void _debug_print(T xarray[], ll n) {
  rep(i, n) _debug_print(xarray[i]);
}

template <typename T> void _debug_print(const V<T> &xlist) {
  for (auto x : xlist) {
    cout << "-- ";
    _debug_print(x);
  }
}

template <typename T> void _debug_print(const set<T> &xset) {
  for (auto x : xset) {
    cout << "-- ";
    _debug_print(x);
  }
}

template <typename TT, typename T> void _debug_print(const M<TT, T> &xlist) {
  for (auto x : xlist) {
    TT k = x.first;
    T v = x.second;
    cout << "====" << endl;
    cout << "K=";
    _debug_print(k);
    cout << "V=";
    _debug_print(v);
  }
}

template <typename TT, typename T> void _debug_print(const map<TT, T> &xlist) {
  for (auto x : xlist) {
    TT k = x.first;
    T v = x.second;
    cout << "====" << endl;
    cout << "K=";
    _debug_print(k);
    cout << "V=";
    _debug_print(v);
  }
}

///////////////////////////////////////////////////////////////////////////////

void _main();
int main() {
  cout << setprecision(12);
#if !DEBUG
  ios::sync_with_stdio(false);
  cin.tie(0);
#endif

  _main();
  return 0;
}

struct MaxFlow {
  V<ll> links[10010];
  ll capacities[10010][10010];
  ll idxs[10010];
  ll nodes;

  MaxFlow(ll nodes) {
    // i == 0       --> S
    // i == nodes+1 --> T
    rep(i, nodes + 2LL) links[i].clear();
    memset(capacities, 0, sizeof(capacities));
    memset(idxs, 0, sizeof(idxs));
    this->nodes = nodes;
  }

  void add_link(ll a, ll b, ll capacity) {
    links[a].pb(b);
    links[b].pb(a);
    debug_printf("a=%lld b=%lld\\n", a, b);
    capacities[a][b] = capacity;
    capacities[b][a] = 0LL;
  }

  bool find_path(deque<ll> &path, set<ll> &checked, ll v) {
    if (checked.find(v) != checked.end())
      return false;

    checked.insert(v);
    path.push_back(v);
    if (v == nodes + 1)
      return true;

    rep(xxx, links[v].size()) {
      ll nv = links[v][(idxs[v]++) % links[v].size()];
      if (capacities[v][nv] == 0)
        continue;
      if (find_path(path, checked, nv))
        return true;
    }

    // checked.erase(v);
    path.pop_back();
    return false;
  }

  ll solve(void) {
    ll ret = 0LL;

    for (;;) {

      set<ll> checked;
      deque<ll> foundq;
      bool is_found = find_path(foundq, checked, 0);

      if (!is_found)
        break;

      V<ll> found;
      while (foundq.size()) {
        ll v = foundq.front();
        foundq.pop_front();
        found.pb(v);
      }

      ll flowcount = 1e18;
      rep(i, (ll)found.size() - 1LL) {
        ll src = found[i];
        ll dst = found[i + 1];
        flowcount = min(flowcount, capacities[src][dst]);
      }
      rep(i, (ll)found.size() - 1LL) {
        ll src = found[i];
        ll dst = found[i + 1];
        capacities[src][dst] -= flowcount;
        capacities[dst][src] += flowcount;
      }
      ret += flowcount;
    }

    return ret;
  }
};

bool valid(const V<string> &grid, ll h, ll w, ll hh, ll ww) {
  if (hh < 0)
    return false;
  if (hh >= h)
    return false;
  if (ww < 0)
    return false;
  if (ww >= w)
    return false;
  if (grid[hh][ww] == '#')
    return false;
  return true;
}

void _main() {
  ll h;
  llin(h);
  ll w;
  llin(w);
  S V<string> grid;
  rep(i, h) {
    string tmp;
    CIN(tmp);
    grid.pb(tmp);
  }

  ll nodes = 10005;
  S MaxFlow flow(nodes);

  rep(hh, h) rep(ww, w) {
    if ((hh + ww) & 1LL)
      flow.add_link(hh * w + ww + 1, nodes + 1, 1);
    else
      flow.add_link(0, hh * w + ww + 1, 1);
  }

  ll diff_h[4] = {-1, 0, 0, 1};
  ll diff_w[4] = {0, -1, 1, 0};
  V<t2> paths;

  rep(hh, h) rep(ww, w) {
    if ((hh + ww) & 1LL)
      continue;
    if (grid[hh][ww] == '#')
      continue;
    rep(i, 4) {
      ll hhh = hh + diff_h[i];
      ll www = ww + diff_w[i];
      if (valid(grid, h, w, hhh, www)) {
        flow.add_link(hh * w + ww + 1, hhh * w + www + 1, 1);
        paths.pb(t2(hh * w + ww + 1, hhh * w + www + 1));
      }
    }
  }

  ll anscnt = flow.solve();

  for (auto path : paths) {
    ll x1 = get<0>(path);
    ll x2 = get<1>(path);
    debug_printf("--------\\n");
    if (flow.capacities[x1][x2])
      continue;
    debug_printf("---- f=%lld\\n", flow.capacities[x1][x2]);
    x1--;
    x2--;
    ll h1 = x1 / w;
    ll w1 = x1 % w;
    ll h2 = x2 / w;
    ll w2 = x2 % w;
    debug_printf("h1=%lld h2=%lld w1=%lld w2=%lld\\n", h1, h2, w1, w2);
    if (h1 == h2) {
      ll wmin = min(w1, w2);
      ll wmax = max(w1, w2);
      grid[h1][wmin] = '>';
      grid[h1][wmax] = '<';
    } else {
      ll hmin = min(h1, h2);
      ll hmax = max(h1, h2);
      grid[hmin][w1] = 'v';
      grid[hmax][w1] = '^';
    }
  }

  debug_printf("----- ans\\n");

  cout << anscnt << endl;
  rep(hh, h) {
    rep(ww, w) { cout << grid[hh][ww]; }
    cout << endl;
  }
}

///////////////////////////////////////////////////////////////////////////////


Error: TLE

Fixed submission:

///////////////////////////////////////////////////////////////////////////////

#include <bits/stdc++.h>
#include <sys/time.h>
#include <time.h>
#include <unistd.h>

using namespace std;

///////////////////////////////////////////////////////////////////////////////

#define DEBUG 0

#define pb push_back
#define V vector
#define M unordered_map
#define S static

#define rep(i, n) for (ll i = 0LL; i < n; ++i)
#define srep(i, s, n) for (ll i = s; i < n; ++i)
#define rrep(i, n) for (ll i = n - 1LL; i >= 0LL; --i)
#define ALL(a) (a).begin(), (a).end()
#define RALL(a) (a).rbegin(), (a).rend()
#define CIN(x)                                                                 \\
  do {                                                                         \\
    assert(!cin.eof());                                                        \\
    cin >> x;                                                                  \\
    assert(!cin.fail());                                                       \\
  } while (0);
#if DEBUG
#define debug_print(...) _debug_print(__VA_ARGS__)
#define debug_printf(...) printf(__VA_ARGS__)
#define debug_print_time _debug_print_time
#else // DEBUG
#define debug_print(...)
#define debug_printf(...)
#define debug_print_time
#endif // DEBUG

typedef long long ll;
typedef unsigned long long ull;
typedef tuple<ll, ll> t2;
typedef tuple<ll, ll, ll> t3;
typedef tuple<ll, ll, ll, ll> t4;
typedef tuple<ll, ll, ll, ll, ll> t5;
template <typename T>
using priority_queue_incr = priority_queue<T, V<T>, greater<T>>;

///////////////////////////////////////////////////////////////////////////////

template <typename TT, typename T> T get_m(M<TT, T> &m, TT k, T default_value) {
  if (m.find(k) == m.end())
    return m[k] = default_value;
  return m[k];
}

template <typename TT, typename T> void incr_m(M<TT, T> &m, TT k) {
  if (m.find(k) == m.end())
    m[k] = 0;
  m[k]++;
}

template <typename TT, typename T> void incr_m(map<TT, T> &m, TT k) {
  if (m.find(k) == m.end())
    m[k] = 0;
  m[k]++;
}

void llin(ll &a) { CIN(a); }

void llinl1(V<ll> &v, ll count) {
  for (ll i = 0LL; i < count; ++i) {
    ll a;
    CIN(a);
    v.push_back(a);
  }
}

void llinl2(V<t2> &v, ll count) {
  for (ll i = 0LL; i < count; ++i) {
    ll a, b;
    CIN(a >> b);
    v.push_back(t2(a, b));
  }
}

void llinl3(V<t3> &v, ll count) {
  for (ll i = 0LL; i < count; ++i) {
    ll a, b, c;
    CIN(a >> b >> c);
    v.push_back(t3(a, b, c));
  }
}

void llinl4(V<t4> &v, ll count) {
  for (ll i = 0LL; i < count; ++i) {
    ll a, b, c, d;
    CIN(a >> b >> c >> d);
    v.push_back(t4(a, b, c, d));
  }
}

void llina(V<ll> &v, ll count) { llinl1(v, count); }

template <typename T> void sort(V<T> &v) { sort(v.begin(), v.end()); }

template <typename T> void sort_reverse(V<T> &v) {
  sort(v.begin(), v.end(), greater<T>());
}

template <typename T> void _debug_print(T x) { cout << x << endl; }

void _debug_print(const t2 &x) {
  ll x1 = get<0>(x);
  ll x2 = get<1>(x);
  cout << "-- " << x1 << " -- " << x2 << endl;
}

void _debug_print(const t3 &x) {
  ll x1 = get<0>(x);
  ll x2 = get<1>(x);
  ll x3 = get<2>(x);
  cout << "-- " << x1 << " -- " << x2 << " -- " << x3 << endl;
}

void _debug_print(const t4 &x) {
  ll x1 = get<0>(x);
  ll x2 = get<1>(x);
  ll x3 = get<2>(x);
  ll x4 = get<3>(x);
  cout << "-- " << x1 << " -- " << x2 << " -- " << x3 << " -- " << x4 << endl;
}

template <typename T> void _debug_print(T xarray[], ll n) {
  rep(i, n) _debug_print(xarray[i]);
}

template <typename T> void _debug_print(const V<T> &xlist) {
  for (auto x : xlist) {
    cout << "-- ";
    _debug_print(x);
  }
}

template <typename T> void _debug_print(const set<T> &xset) {
  for (auto x : xset) {
    cout << "-- ";
    _debug_print(x);
  }
}

template <typename TT, typename T> void _debug_print(const M<TT, T> &xlist) {
  for (auto x : xlist) {
    TT k = x.first;
    T v = x.second;
    cout << "====" << endl;
    cout << "K=";
    _debug_print(k);
    cout << "V=";
    _debug_print(v);
  }
}

template <typename TT, typename T> void _debug_print(const map<TT, T> &xlist) {
  for (auto x : xlist) {
    TT k = x.first;
    T v = x.second;
    cout << "====" << endl;
    cout << "K=";
    _debug_print(k);
    cout << "V=";
    _debug_print(v);
  }
}

///////////////////////////////////////////////////////////////////////////////

void _main();
int main() {
  cout << setprecision(12);
#if !DEBUG
  ios::sync_with_stdio(false);
  cin.tie(0);
#endif

  _main();
  return 0;
}

struct MaxFlow {
  V<ll> links[10010];
  ll capacities[10010][10010];
  ll nodes;

  MaxFlow(ll nodes) {
    // i == 0       --> S
    // i == nodes+1 --> T
    rep(i, nodes + 2LL) links[i].clear();
    memset(capacities, 0, sizeof(capacities));
    this->nodes = nodes;
  }

  void add_link(ll a, ll b, ll capacity) {
    links[a].pb(b);
    links[b].pb(a);
    debug_printf("a=%lld b=%lld\\n", a, b);
    capacities[a][b] = capacity;
    capacities[b][a] = 0LL;
  }

  bool find_path(deque<ll> &path, set<ll> &checked, ll v) {
    if (checked.find(v) != checked.end())
      return false;

    checked.insert(v);
    path.push_back(v);
    if (v == nodes + 1)
      return true;

    for (auto nv : links[v]) {
      if (capacities[v][nv] == 0)
        continue;
      if (find_path(path, checked, nv))
        return true;
    }

    checked.erase(v);
    path.pop_back();
    return false;
  }

  ll solve(void) {
    ll ret = 0LL;

    for (;;) {

      set<ll> checked;
      deque<ll> foundq;
      bool is_found = find_path(foundq, checked, 0);

      debug_printf("is_found=%d\\n", is_found);

      if (!is_found)
        break;

      V<ll> found;
      while (foundq.size()) {
        ll v = foundq.front();
        foundq.pop_front();
        found.pb(v);
      }

      ll flowcount = 1e18;
      rep(i, (ll)found.size() - 1LL) {
        ll src = found[i];
        ll dst = found[i + 1];
        flowcount = min(flowcount, capacities[src][dst]);
      }
      rep(i, (ll)found.size() - 1LL) {
        ll src = found[i];
        ll dst = found[i + 1];
        if (src && dst < 1000) {
          debug_printf("src=%lld dst=%lld\\n", src, dst);
        }
        capacities[src][dst] -= flowcount;
        capacities[dst][src] += flowcount;
      }
      ret += flowcount;
    }

    return ret;
  }
};

bool valid(const V<string> &grid, ll h, ll w, ll hh, ll ww) {
  if (hh < 0)
    return false;
  if (hh >= h)
    return false;
  if (ww < 0)
    return false;
  if (ww >= w)
    return false;
  if (grid[hh][ww] == '#')
    return false;
  return true;
}

void _main() {
  ll h;
  llin(h);
  ll w;
  llin(w);
  S V<string> grid;
  rep(i, h) {
    string tmp;
    CIN(tmp);
    grid.pb(tmp);
  }

  ll nodes = 10005;
  S MaxFlow flow(nodes);

  rep(hh, h) rep(ww, w) {
    if ((hh + ww) & 1LL)
      flow.add_link(hh * w + ww + 1, nodes + 1, 1);
    else
      flow.add_link(0, hh * w + ww + 1, 1);
  }

  ll diff_h[4] = {-1, 0, 0, 1};
  ll diff_w[4] = {0, -1, 1, 0};
  V<t2> paths;

  rep(hh, h) rep(ww, w) {
    if ((hh + ww) & 1LL)
      continue;
    if (grid[hh][ww] == '#')
      continue;
    rep(i, 4) {
      ll hhh = hh + diff_h[i];
      ll www = ww + diff_w[i];
      if (valid(grid, h, w, hhh, www)) {
        flow.add_link(hh * w + ww + 1, hhh * w + www + 1, 1);
        paths.pb(t2(hh * w + ww + 1, hhh * w + www + 1));
      }
    }
  }

  ll anscnt = flow.solve();

  for (auto path : paths) {
    ll x1 = get<0>(path);
    ll x2 = get<1>(path);
    debug_printf("--------\\n");
    if (flow.capacities[x1][x2])
      continue;
    debug_printf("---- f=%lld\\n", flow.capacities[x1][x2]);
    x1--;
    x2--;
    ll h1 = x1 / w;
    ll w1 = x1 % w;
    ll h2 = x2 / w;
    ll w2 = x2 % w;
    debug_printf("h1=%lld h2=%lld w1=%lld w2=%lld\\n", h1, h2, w1, w2);
    if (h1 == h2) {
      ll wmin = min(w1, w2);
      ll wmax = max(w1, w2);
      grid[h1][wmin] = '>';
      grid[h1][wmax] = '<';
    } else {
      ll hmin = min(h1, h2);
      ll hmax = max(h1, h2);
      grid[hmin][w1] = 'v';
      grid[hmax][w1] = '^';
    }
  }

  debug_printf("----- ans\\n");

  cout << anscnt << endl;
  rep(hh, h) {
    rep(ww, w) { cout << grid[hh][ww]; }
    cout << endl;
  }
}

///////////////////////////////////////////////////////////////////////////////