Problem p03205 (C++)

Buggy submission (status: Time Limit Exceeded):
#include <bits/stdc++.h>
using namespace std;

const int N = 201000;

int chosen[N];

namespace MF {
struct Edge {
  int v, flow, ne;
} e[N << 3];

int fi[N], tot, S, T, V, cur[N], dis[N], q[N];

void Init(int s, int t, int v) {
  S = s;
  T = t;
  V = v;
  tot = 1;
  for (int i = 0; i < V; i++) {
    fi[i] = 0;
  }
}

void Add(int x, int y, int w) {
  e[++tot] = {y, w, fi[x]};
  fi[x] = tot;
  e[++tot] = {x, 0, fi[y]};
  fi[y] = tot;
}

bool Bfs(void) {
  for (int i = 0; i < V; i++) {
    dis[i] = 0;
  }
  int h = 1, t = 0;
  q[++t] = S;
  dis[S] = 1;
  while (h <= t) {
    int x = q[h++];
    for (int i = fi[x]; i; i = e[i].ne) {
      if (e[i].flow && !dis[e[i].v]) {
        dis[e[i].v] = dis[x] + 1;
        q[++t] = e[i].v;
      }
    }
  }
  return dis[T];
}

int Dfs(int x, int f) {
  if (x == T) {
    return f;
  }
  int used = 0;
  for (int &i = cur[x]; i; i = e[i].ne) {
    if (e[i].flow && dis[e[i].v] == dis[x] + 1) {
      int t = Dfs(e[i].v, min(f - used, e[i].flow));
      used += t;
      e[i].flow -= t;
      e[i ^ 1].flow += t;
      if (used == f) {
        return used;
      }
    }
  }
  dis[x] = -1;
  return used;
}

int Solve(void) {
  int ans = 0;
  while (Bfs()) {
    for (int i = 0; i < V; i++) {
      cur[i] = fi[i];
    }
    ans += Dfs(S, 1e9);
  }
  for (int i = 1; i < (V >> 1); i++) {
    for (int j = fi[i]; j; j = e[j].ne) {
      if (!e[j].flow) {
        ::chosen[i] = e[j].v - (V >> 1) + 1;
      }
    }
  }
  return ans;
}
} // namespace MF

int n, q[N], full[N];
pair<int, int> ans[N];
vector<int> in[N];

int main(void) {
  scanf("%d", &n);
  MF::Init(0, n << 1 ^ 3, n << 1);
  for (int i = 1, k; i < n; i++) {
    scanf("%d", &k);
    for (int j = 0, x; j < k; j++) {
      scanf("%d", &x);
      x--;
      if (x) {
        MF::Add(i, x + n - 1, 1);
      }
      in[x].push_back(i);
    }
  }
  for (int i = 1; i < n; i++) {
    MF::Add(MF::S, i, 1);
    MF::Add(i + n - 1, MF::T, 1);
  }
  if (MF::Solve() < n - 1) {
    return puts("-1"), 0;
  }
  int h = 1, t = 0;
  q[++t] = 0;
  while (h <= t) {
    int x = q[h++];
    for (int y : in[x]) {
      if (full[y]) {
        continue;
      }
      full[y] = 1;
      q[++t] = chosen[y];
      ans[y] = {x, chosen[y]};
    }
  }
  if (t < n) {
    puts("-1");
  } else {
    for (int i = 1; i < n; i++) {
      printf("%d %d\n", ans[i].first + 1, ans[i].second + 1);
    }
  }
  return 0;
}


Fixed submission:
#include <bits/stdc++.h>
using namespace std;

const int N = 201000;

int chosen[N];

namespace MF {
struct Edge {
  int v, flow, ne;
} e[N << 3];

int fi[N], tot, S, T, V, cur[N], dis[N], q[N];

void Init(int s, int t, int v) {
  S = s;
  T = t;
  V = v;
  tot = 1;
  for (int i = 0; i < V; i++) {
    fi[i] = 0;
  }
}

void Add(int x, int y, int w) {
  e[++tot] = {y, w, fi[x]};
  fi[x] = tot;
  e[++tot] = {x, 0, fi[y]};
  fi[y] = tot;
}

bool Bfs(void) {
  for (int i = 0; i < V; i++) {
    dis[i] = 0;
  }
  int h = 1, t = 0;
  q[++t] = S;
  dis[S] = 1;
  while (h <= t) {
    int x = q[h++];
    for (int i = fi[x]; i; i = e[i].ne) {
      if (e[i].flow && !dis[e[i].v]) {
        dis[e[i].v] = dis[x] + 1;
        q[++t] = e[i].v;
      }
    }
  }
  return dis[T];
}

int Dfs(int x, int f) {
  if (x == T) {
    return f;
  }
  int used = 0;
  for (int &i = cur[x]; i; i = e[i].ne) {
    if (e[i].flow && dis[e[i].v] == dis[x] + 1) {
      int t = Dfs(e[i].v, min(f - used, e[i].flow));
      used += t;
      e[i].flow -= t;
      e[i ^ 1].flow += t;
      if (used == f) {
        return used;
      }
    }
  }
  dis[x] = -1;
  return used;
}

int Solve(void) {
  int ans = 0;
  while (Bfs()) {
    for (int i = 0; i < V; i++) {
      cur[i] = fi[i];
    }
    ans += Dfs(S, 1e9);
  }
  for (int i = 1; i < (V >> 1); i++) {
    for (int j = fi[i]; j; j = e[j].ne) {
      if (!e[j].flow) {
        ::chosen[i] = e[j].v - (V >> 1) + 1;
      }
    }
  }
  return ans;
}
} // namespace MF

int n, q[N], full[N];
pair<int, int> ans[N];
vector<int> in[N];

int main(void) {
  scanf("%d", &n);
  MF::Init(0, n * 2 - 1, n << 1);
  for (int i = 1, k; i < n; i++) {
    scanf("%d", &k);
    for (int j = 0, x; j < k; j++) {
      scanf("%d", &x);
      x--;
      if (x) {
        MF::Add(i, x + n - 1, 1);
      }
      in[x].push_back(i);
    }
  }
  for (int i = 1; i < n; i++) {
    MF::Add(MF::S, i, 1);
    MF::Add(i + n - 1, MF::T, 1);
  }
  if (MF::Solve() < n - 1) {
    return puts("-1"), 0;
  }
  int h = 1, t = 0;
  q[++t] = 0;
  while (h <= t) {
    int x = q[h++];
    for (int y : in[x]) {
      if (full[y]) {
        continue;
      }
      full[y] = 1;
      q[++t] = chosen[y];
      ans[y] = {x, chosen[y]};
    }
  }
  if (t < n) {
    puts("-1");
  } else {
    for (int i = 1; i < n; i++) {
      printf("%d %d\n", ans[i].first + 1, ans[i].second + 1);
    }
  }
  return 0;
}