Problem p03335 (C++)

Buggy submission (status: Runtime Error):

#include <cstdio>
#include <cstring>
#include <vector>

using namespace std;
const int Max_N(2050);
const int Max_M(2050);
typedef pair<int, int> pil;
#define mp make_pair
#define fi first
#define se second

namespace io {
const int SIZE = (1 << 21) + 1;
char ibuf[SIZE], *iS, *iT, obuf[SIZE], *oS = obuf, *oT = oS + SIZE - 1, c,
                                       qu[55];
int f, qr;
#define gc()                                                                   \
  (iS == iT ? (iT = (iS = ibuf) + fread(ibuf, 1, SIZE, stdin),                 \
               (iS == iT ? EOF : *iS++))                                       \
            : *iS++)
inline void flush() {
  fwrite(obuf, 1, oS - obuf, stdout);
  oS = obuf;
}
inline void putc(char x) {
  *oS++ = x;
  if (oS == oT)
    flush();
}
template <class I> inline void gi(I &x) {
  for (f = 1, c = gc(); c < '0' || c > '9'; c = gc())
    if (c == '-')
      f = -1;
  for (x = 0; c <= '9' && c >= '0'; c = gc())
    x = x * 10 + (c & 15);
  x *= f;
}
template <class I> inline void print(I x) {
  if (!x)
    putc('0');
  if (x < 0)
    putc('-'), x = -x;
  while (x)
    qu[++qr] = x % 10 + '0', x /= 10;
  while (qr)
    putc(qu[qr--]);
}
struct Flusher_ {
  ~Flusher_() { flush(); }
} io_flusher_;
} // namespace io
using io::gi;
using io::print;
using io::putc;

int N, M, Head[Max_N], Total, To[Max_N << 1], Next[Max_N << 1], A[Max_M],
    B[Max_M], Dir[Max_M], Father[Max_N], Deep[Max_N], Son[Max_N], Q[Max_N];
int Cnt1[Max_N], Cnt2[Max_N], Ans;

inline void Add_Edge(int s, int t) {
  ++Total, To[Total] = t, Next[Total] = Head[s], Head[s] = Total;
}

void dfs(int u) {
  for (int i = Head[u], v; i; i = Next[i])
    if ((v = To[i]) != Father[u])
      Father[v] = u, Deep[v] = Deep[u] + 1, dfs(v), ++Son[u];
}

bool done[Max_N];

int LCA(int u, int v) {
  memset(done, false, sizeof(done));
  for (; u; u = Father[u])
    done[u] = true;
  for (; v; v = Father[v])
    if (done[v])
      return v;
}

struct path {
  int s, t;
  vector<pil> v;
};
vector<path> V[2], T;

void getAns(int u) {
  for (int i = Head[u], v; i; i = Next[i])
    if ((v = To[i]) != Father[u])
      getAns(v), Cnt1[u] += Cnt1[v], Cnt2[u] += Cnt2[v];
  Ans += (Cnt1[u] > 0) + (Cnt2[u] > 0);
}

int main() {
  gi(N), gi(M);
  for (int i = 1, u, v; i != N; ++i)
    gi(u), gi(v), Add_Edge(u, v), Add_Edge(v, u);
  dfs(1);
  for (int i = 1; i <= M; ++i) {
    gi(A[i]), gi(B[i]);
    path a;
    a.s = A[i], a.t = B[i], a.v.push_back(mp(i, 0)), V[0].push_back(a);
  }
  for (int u = 1; u <= N; ++u)
    if (!Son[u])
      Q[++Q[0]] = u;
  for (int ft = 1, now = 1, nxt = 0, u; ft <= Q[0];) {
    u = Q[ft++], now ^= 1, nxt ^= 1, V[nxt].clear(), T.clear();
    if (u == 1)
      break;
    if ((--Son[Father[u]]) == 0)
      Q[++Q[0]] = Father[u];
    for (int i = 0; i < V[now].size(); ++i)
      if (V[now][i].s == u || V[now][i].t == u) {
        T.push_back(V[now][i]);
        if (V[now][i].t == u) {
          swap(T.back().s, T.back().t);
          for (int j = 0; j < T.back().v.size(); ++j)
            T.back().v[j].se ^= 1;
        }
      } else
        V[nxt].push_back(V[now][i]);
    while (T.empty() == false)
      if (T.size() == 1) {
        path t = T.back();
        T.pop_back();
        if ((t.s = Father[t.s]) != t.t)
          V[nxt].push_back(t);
        else
          for (int j = 0; j < T.back().v.size(); ++j)
            Dir[T.back().v[j].fi] = T.back().v[j].se;
      } else {
        path t1 = T.back();
        T.pop_back();
        path t2 = T.back();
        T.pop_back();
        if (t1.t != t2.t) {
          path t;
          t.s = t1.t, t.t = t2.t;
          for (int j = 0; j < t1.v.size(); ++j)
            t1.v[j].se ^= 1, t.v.push_back(t1.v[j]);
          for (int j = 0; j < t2.v.size(); ++j)
            t.v.push_back(t2.v[j]);
          V[nxt].push_back(t);
        } else {
          for (int j = 0; j < t1.v.size(); ++j)
            Dir[t1.v[j].fi] = (t1.v[j].se ^ 1);
          for (int j = 0; j < t2.v.size(); ++j)
            Dir[t2.v[j].fi] = t2.v[j].se;
        }
      }
  }
  for (int i = 1, lca; i <= M; ++i) {
    lca = LCA(A[i], B[i]);
    if (Dir[i] == 0)
      ++Cnt1[A[i]], --Cnt1[lca], ++Cnt2[B[i]], --Cnt2[lca];
    else
      ++Cnt1[B[i]], --Cnt1[lca], ++Cnt2[A[i]], --Cnt2[lca];
  }
  getAns(1);
  print(Ans), putc('\n');
  for (int i = 1, lca; i <= M; ++i) {
    if (Dir[i] == 0)
      print(A[i]), putc(' '), print(B[i]);
    else
      print(B[i]), putc(' '), print(A[i]);
    putc('\n');
  }
  return 0;
}

Fixed submission:

#include <cstdio>
#include <cstring>
#include <vector>

using namespace std;
const int Max_N(2050);
const int Max_M(2050);
typedef pair<int, int> pil;
#define mp make_pair
#define fi first
#define se second

namespace io {
const int SIZE = (1 << 21) + 1;
char ibuf[SIZE], *iS, *iT, obuf[SIZE], *oS = obuf, *oT = oS + SIZE - 1, c,
                                       qu[55];
int f, qr;
#define gc()                                                                   \
  (iS == iT ? (iT = (iS = ibuf) + fread(ibuf, 1, SIZE, stdin),                 \
               (iS == iT ? EOF : *iS++))                                       \
            : *iS++)
inline void flush() {
  fwrite(obuf, 1, oS - obuf, stdout);
  oS = obuf;
}
inline void putc(char x) {
  *oS++ = x;
  if (oS == oT)
    flush();
}
template <class I> inline void gi(I &x) {
  for (f = 1, c = gc(); c < '0' || c > '9'; c = gc())
    if (c == '-')
      f = -1;
  for (x = 0; c <= '9' && c >= '0'; c = gc())
    x = x * 10 + (c & 15);
  x *= f;
}
template <class I> inline void print(I x) {
  if (!x)
    putc('0');
  if (x < 0)
    putc('-'), x = -x;
  while (x)
    qu[++qr] = x % 10 + '0', x /= 10;
  while (qr)
    putc(qu[qr--]);
}
struct Flusher_ {
  ~Flusher_() { flush(); }
} io_flusher_;
} // namespace io
using io::gi;
using io::print;
using io::putc;

int N, M, Head[Max_N], Total, To[Max_N << 1], Next[Max_N << 1], A[Max_M],
    B[Max_M], Dir[Max_M], Father[Max_N], Deep[Max_N], Son[Max_N], Q[Max_N];
int Cnt1[Max_N], Cnt2[Max_N], Ans;

inline void Add_Edge(int s, int t) {
  ++Total, To[Total] = t, Next[Total] = Head[s], Head[s] = Total;
}

void dfs(int u) {
  for (int i = Head[u], v; i; i = Next[i])
    if ((v = To[i]) != Father[u])
      Father[v] = u, Deep[v] = Deep[u] + 1, dfs(v), ++Son[u];
}

bool done[Max_N];

int LCA(int u, int v) {
  memset(done, false, sizeof(done));
  for (; u; u = Father[u])
    done[u] = true;
  for (; v; v = Father[v])
    if (done[v])
      return v;
}

struct path {
  int s, t;
  vector<pil> v;
};
vector<path> V[2], T;

void getAns(int u) {
  for (int i = Head[u], v; i; i = Next[i])
    if ((v = To[i]) != Father[u])
      getAns(v), Cnt1[u] += Cnt1[v], Cnt2[u] += Cnt2[v];
  Ans += (Cnt1[u] > 0) + (Cnt2[u] > 0);
}

int main() {
  gi(N), gi(M);
  for (int i = 1, u, v; i != N; ++i)
    gi(u), gi(v), Add_Edge(u, v), Add_Edge(v, u);
  dfs(1);
  for (int i = 1; i <= M; ++i) {
    gi(A[i]), gi(B[i]);
    path a;
    a.s = A[i], a.t = B[i], a.v.push_back(mp(i, 0)), V[0].push_back(a);
  }
  for (int u = 1; u <= N; ++u)
    if (!Son[u])
      Q[++Q[0]] = u;
  for (int ft = 1, now = 1, nxt = 0, u; ft <= Q[0];) {
    u = Q[ft++], now ^= 1, nxt ^= 1, V[nxt].clear(), T.clear();
    if (u == 1)
      break;
    if ((--Son[Father[u]]) == 0)
      Q[++Q[0]] = Father[u];
    for (int i = 0; i < V[now].size(); ++i)
      if (V[now][i].s == u || V[now][i].t == u) {
        T.push_back(V[now][i]);
        if (V[now][i].t == u) {
          swap(T.back().s, T.back().t);
          for (int j = 0; j < T.back().v.size(); ++j)
            T.back().v[j].se ^= 1;
        }
      } else
        V[nxt].push_back(V[now][i]);
    while (T.empty() == false)
      if (T.size() == 1) {
        path t = T.back();
        T.pop_back();
        if ((t.s = Father[t.s]) != t.t)
          V[nxt].push_back(t);
        else
          for (int j = 0; j < t.v.size(); ++j)
            Dir[t.v[j].fi] = t.v[j].se;
      } else {
        path t1 = T.back();
        T.pop_back();
        path t2 = T.back();
        T.pop_back();
        if (t1.t != t2.t) {
          path t;
          t.s = t1.t, t.t = t2.t;
          for (int j = 0; j < t1.v.size(); ++j)
            t1.v[j].se ^= 1, t.v.push_back(t1.v[j]);
          for (int j = 0; j < t2.v.size(); ++j)
            t.v.push_back(t2.v[j]);
          V[nxt].push_back(t);
        } else {
          for (int j = 0; j < t1.v.size(); ++j)
            Dir[t1.v[j].fi] = (t1.v[j].se ^ 1);
          for (int j = 0; j < t2.v.size(); ++j)
            Dir[t2.v[j].fi] = t2.v[j].se;
        }
      }
  }
  for (int i = 1, lca; i <= M; ++i) {
    lca = LCA(A[i], B[i]);
    if (Dir[i] == 0)
      ++Cnt1[A[i]], --Cnt1[lca], ++Cnt2[B[i]], --Cnt2[lca];
    else
      ++Cnt1[B[i]], --Cnt1[lca], ++Cnt2[A[i]], --Cnt2[lca];
  }
  getAns(1);
  print(Ans), putc('\n');
  for (int i = 1, lca; i <= M; ++i) {
    if (Dir[i] == 0)
      print(A[i]), putc(' '), print(B[i]);
    else
      print(B[i]), putc(' '), print(A[i]);
    putc('\n');
  }
  return 0;
}