Problem p03205 (C++)

Buggy submission (status: Runtime Error):
// Jump, and you will find out how to unfold your wings as you fall.

#include <bits/stdc++.h>

#define F first
#define S second
#define PB push_back
#define sz(s) int((s).size())
#define bit(n, k) (((n) >> (k)) & 1)

using namespace std;

typedef long long ll;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;

const int maxn = 1e5 + 10, Src = maxn - 3, Snk = maxn - 2, inf = 1e8;

vector<pii> v[maxn];
vector<int> vid[maxn];
bool mark[maxn];
pii ans[maxn];
int n, h[maxn], pt[maxn];

void add_edge(int a, int b) {
  vid[a].PB(sz(v[b]));
  vid[b].PB(sz(v[a]));
  v[a].PB({b, 1});
  v[b].PB({a, 0});
}

bool bfs() {
  memset(mark, 0, sizeof mark);
  queue<int> q;
  q.push(Src);
  mark[Src] = 1;
  while (sz(q)) {
    int u = q.front();
    if (u == Snk)
      return 1;
    q.pop();
    for (pii p : v[u]) {
      if (p.S > 0 && mark[p.F] == 0) {
        h[p.F] = h[u] + 1;
        mark[p.F] = 1;
        q.push(p.F);
      }
    }
  }
  return 0;
}
int dfs(int u, int flw = inf) {
  if (u == Snk)
    return flw;
  int ans = 0, &i = pt[u];
  while (i < sz(v[u])) {
    int y = v[u][i].F, &w = v[u][i].S, &w2 = v[y][vid[u][i]].S;
    if (w > 0 && h[u] + 1 == h[y]) {
      int num = dfs(y, min(flw - ans, w));
      w -= num, w2 += num, ans += num;
      if (ans == flw)
        return ans;
    }
    ++i;
  }
  return ans;
}
int flow() {
  int ans = 0;
  while (bfs()) {
    memset(pt, 0, sizeof pt);
    ans += dfs(Src);
  }
  return ans;
}

void go(int u, int par = -1) {
  mark[u] = 1;
  if (u >= n && u != Src && u != Snk) {
    int y = -1;
    for (pii p : v[u]) {
      if (p.S != 0)
        y = p.F;
    }
    ans[u - n] = {par + 1, y + 1};
  }
  for (pii p : v[u]) {
    if (p.S != 0 && mark[p.F] == 0)
      go(p.F, u);
  }
}

int main() {
  ios_base::sync_with_stdio(0);
  cin.tie();
  cin >> n;
  for (int i = 0; i < n - 1; i++) {
    int N;
    cin >> N;
    while (N--) {
      int x;
      cin >> x;
      add_edge(--x, i + n);
    }
  }
  for (int i = 0; i < n; i++) {
    add_edge(Src, i);
  }
  for (int i = n; i < 2 * n - 1; i++) {
    add_edge(i, Snk);
  }
  int num = flow();
  if (num != n - 1)
    return cout << -1 << endl, 0;
  memset(mark, 0, sizeof mark);
  go(Src);
  for (int i = 0; i < n - 1; i++) {
    if (ans[i].F == 0)
      return cout << -1 << endl, 0;
  }
  for (int i = 0; i < n - 1; i++) {
    cout << ans[i].F << " " << ans[i].S << "\n";
  }
}

// Deathly mistakes:
//  * Read the problem curfully.
//  * Check maxn.
//  * Overflows.


Fixed submission:
// Jump, and you will find out how to unfold your wings as you fall.

#include <bits/stdc++.h>

#define F first
#define S second
#define PB push_back
#define sz(s) int((s).size())
#define bit(n, k) (((n) >> (k)) & 1)

using namespace std;

typedef long long ll;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;

const int maxn = 2e5 + 10, Src = maxn - 3, Snk = maxn - 2, inf = 1e8;

vector<pii> v[maxn];
vector<int> vid[maxn];
bool mark[maxn];
pii ans[maxn];
int n, h[maxn], pt[maxn];

void add_edge(int a, int b) {
  vid[a].PB(sz(v[b]));
  vid[b].PB(sz(v[a]));
  v[a].PB({b, 1});
  v[b].PB({a, 0});
}

bool bfs() {
  memset(mark, 0, sizeof mark);
  queue<int> q;
  q.push(Src);
  mark[Src] = 1;
  while (sz(q)) {
    int u = q.front();
    if (u == Snk)
      return 1;
    q.pop();
    for (pii p : v[u]) {
      if (p.S > 0 && mark[p.F] == 0) {
        h[p.F] = h[u] + 1;
        mark[p.F] = 1;
        q.push(p.F);
      }
    }
  }
  return 0;
}
int dfs(int u, int flw = inf) {
  if (u == Snk)
    return flw;
  int ans = 0, &i = pt[u];
  while (i < sz(v[u])) {
    int y = v[u][i].F, &w = v[u][i].S, &w2 = v[y][vid[u][i]].S;
    if (w > 0 && h[u] + 1 == h[y]) {
      int num = dfs(y, min(flw - ans, w));
      w -= num, w2 += num, ans += num;
      if (ans == flw)
        return ans;
    }
    ++i;
  }
  return ans;
}
int flow() {
  int ans = 0;
  while (bfs()) {
    memset(pt, 0, sizeof pt);
    ans += dfs(Src);
  }
  return ans;
}

void go(int u, int par = -1) {
  mark[u] = 1;
  if (u >= n && u != Src && u != Snk) {
    int y = -1;
    for (pii p : v[u]) {
      if (p.S != 0)
        y = p.F;
    }
    ans[u - n] = {par + 1, y + 1};
  }
  for (pii p : v[u]) {
    if (p.S != 0 && mark[p.F] == 0)
      go(p.F, u);
  }
}

int main() {
  ios_base::sync_with_stdio(0);
  cin.tie();
  cin >> n;
  for (int i = 0; i < n - 1; i++) {
    int N;
    cin >> N;
    while (N--) {
      int x;
      cin >> x;
      add_edge(--x, i + n);
    }
  }
  for (int i = 0; i < n; i++) {
    add_edge(Src, i);
  }
  for (int i = n; i < 2 * n - 1; i++) {
    add_edge(i, Snk);
  }
  int num = flow();
  if (num != n - 1)
    return cout << -1 << endl, 0;
  memset(mark, 0, sizeof mark);
  go(Src);
  for (int i = 0; i < n - 1; i++) {
    if (ans[i].F == 0)
      return cout << -1 << endl, 0;
  }
  for (int i = 0; i < n - 1; i++) {
    cout << ans[i].F << " " << ans[i].S << "\n";
  }
}

// Deathly mistakes:
//  * Read the problem curfully.
//  * Check maxn.
//  * Overflows.