Problem p03205 (C++)

Buggy submission (status: Runtime Error):
#include <algorithm>
#include <cstdio>
#include <cstring>
#include <queue>
using namespace std;

#define FILL(a, n, x) memset((a), (x), sizeof((a)[0]) * (n))
#define FILLA(a, x) memset((a), (x), sizeof(a))
#define COPY(a, n, b) memcpy((b), (a), sizeof((a)[0]) * (n))
#define COPYA(a, b) memcpy((b), (a), sizeof(a))

typedef unsigned long long lu;
typedef long long li;
typedef pair<int, int> pii;
const int mod = 1e9 + 7;

inline int Add(int x) { return x >= mod ? x - mod : x; }
inline void Add(int &x, int y) {
  x += y;
  if (x >= mod)
    x -= mod;
}
inline int Sub(int x) { return x < 0 ? x + mod : x; }
inline void Sub(int &x, int y) { x = Sub(x - y); }
inline int Mul(int x, int y) { return (int)((lu)x * y % mod); }
inline int Mul(int x, int y, int z) { return (int)((lu)x * y % mod * z % mod); }

int Pow(int x, int y) {
  int z = 1;
  for (; y; y >>= 1) {
    if (y & 1)
      z = Mul(z, x);
    x = Mul(x, x);
  }
  return z;
}

int Inv(int x) { return Pow(x, mod - 2); }
template <class T> inline void Max(T &x, T y) {
  if (y > x)
    x = y;
}
template <class T> inline void Min(T &x, T y) {
  if (y < x)
    x = y;
}

// ----------------------------------------

namespace dinic {
const int maxn = 1e5, maxm = 1e6;
typedef int FlowType;
const FlowType inf_f = ~0U >> 1;

void Init(int n);
void AddEdge(int u, int v, FlowType cap, li id);
FlowType Solve(int s, int t);
vector<pair<li, FlowType>> Result(void);
} // namespace dinic

namespace dinic {
struct Edge {
  int v;
  li id;
  FlowType cap, cap0;
} edge[maxm << 1];

int n, m, s, t;
vector<int> g[maxn];

void Init(int _n) {
  n = _n, m = 0;
  for (int i = 0; i < n; ++i)
    g[i].clear();
}

void AddEdge(int u, int v, FlowType c, li id = -1) {
  g[u].push_back(m);
  edge[m++] = (Edge){v, id, c, c};
  g[v].push_back(m);
  edge[m++] = (Edge){u, id, 0, 0};
}

int iter[maxn], dist[maxn];

bool Bfs(void) {
  queue<int> que;
  que.push(s);
  FILL(dist, n, -1);
  dist[s] = 0;
  while (!que.empty()) {
    int u = que.front();
    que.pop();
    for (int i = 0; i < g[u].size(); ++i) {
      Edge &e = edge[g[u][i]];
      if (e.cap && dist[e.v] == -1) {
        dist[e.v] = dist[u] + 1;
        que.push(e.v);
      }
    }
  }
  return dist[t] >= 0;
}

FlowType Dfs(int u, FlowType f) {
  if (u == t)
    return f;
  FlowType sum = 0;
  for (int &i = iter[u]; i < g[u].size(); ++i) {
    Edge &e = edge[g[u][i]], &rev = edge[g[u][i] ^ 1];
    if (e.cap && dist[e.v] == dist[u] + 1) {
      FlowType res = Dfs(e.v, min(f - sum, e.cap));
      e.cap -= res;
      rev.cap += res;
      if ((sum += res) == f)
        break;
    }
  }
  return sum;
}

FlowType Solve(int _s, int _t) {
  s = _s, t = _t;
  FlowType ans = 0;
  while (Bfs()) {
    FILL(iter, n, 0);
    ans += Dfs(s, inf_f);
  }
  return ans;
}

vector<pair<li, FlowType>> Result(void) {
  vector<pair<li, FlowType>> ans;
  for (int u = 0; u < n; ++u) {
    for (int i = 0; i < g[u].size(); ++i) {
      Edge &e = edge[g[u][i]];
      if (e.cap < e.cap0 && e.id != -1) {
        ans.push_back(make_pair(e.id, e.cap0 - e.cap));
      }
    }
  }
  return ans;
}
} // namespace dinic

// ----------------------------------------

const int maxn = 1e5;
int n;
vector<int> E[maxn];
vector<int> F[maxn];

int match[maxn], par[maxn];
int A[maxn], B[maxn];

void NoSolution(void) {
  puts("-1");
  exit(0);
}

int main(void) {
  scanf("%d", &n);
  for (int i = 0; i < n - 1; ++i) {
    int c;
    scanf("%d", &c);
    while (c--) {
      int x;
      scanf("%d", &x);
      --x;
      E[i].push_back(x);
      F[x].push_back(i);
    }
  }

  // root = 0
  int L = 0, R = n, S = R + n - 1, T = S + 1, N = T + 1;
  dinic::Init(N);
  for (int i = 1; i < n; ++i) {
    dinic::AddEdge(S, L + i, 1, -1);
  }
  for (int i = 0; i < n - 1; ++i) {
    dinic::AddEdge(R + i, T, 1, -1);
  }
  for (int i = 1; i < n; ++i) {
    for (int j : F[i]) {
      dinic::AddEdge(L + i, R + j, 1, (li)i * n + j);
    }
  }
  int flow = dinic::Solve(S, T);
  if (flow < n - 1)
    NoSolution();

  vector<pair<li, int>> way = dinic::Result();
  for (pair<li, int> p : way) {
    int x = (int)(p.first / n), y = (int)(p.first % n);
    match[y] = x;
  }

  queue<int> que;
  que.push(0);
  FILL(par, n, -1);
  while (!que.empty()) {
    int u = que.front();
    que.pop();
    for (int j : F[u]) {
      int i = match[j];
      if (par[i] == -1) {
        par[i] = u;
        A[j] = i;
        B[j] = u;
        que.push(i);
      }
    }
  }
  for (int i = 1; i < n; ++i) {
    if (par[i] == -1)
      NoSolution();
  }
  for (int i = 0; i < n - 1; ++i) {
    printf("%d %d\n", A[i] + 1, B[i] + 1);
  }
  return 0;
}


Fixed submission:
#include <algorithm>
#include <cstdio>
#include <cstring>
#include <queue>
using namespace std;

#define FILL(a, n, x) memset((a), (x), sizeof((a)[0]) * (n))
#define FILLA(a, x) memset((a), (x), sizeof(a))
#define COPY(a, n, b) memcpy((b), (a), sizeof((a)[0]) * (n))
#define COPYA(a, b) memcpy((b), (a), sizeof(a))

typedef unsigned long long lu;
typedef long long li;
typedef pair<int, int> pii;
const int mod = 1e9 + 7;

inline int Add(int x) { return x >= mod ? x - mod : x; }
inline void Add(int &x, int y) {
  x += y;
  if (x >= mod)
    x -= mod;
}
inline int Sub(int x) { return x < 0 ? x + mod : x; }
inline void Sub(int &x, int y) { x = Sub(x - y); }
inline int Mul(int x, int y) { return (int)((lu)x * y % mod); }
inline int Mul(int x, int y, int z) { return (int)((lu)x * y % mod * z % mod); }

int Pow(int x, int y) {
  int z = 1;
  for (; y; y >>= 1) {
    if (y & 1)
      z = Mul(z, x);
    x = Mul(x, x);
  }
  return z;
}

int Inv(int x) { return Pow(x, mod - 2); }
template <class T> inline void Max(T &x, T y) {
  if (y > x)
    x = y;
}
template <class T> inline void Min(T &x, T y) {
  if (y < x)
    x = y;
}

// ----------------------------------------

namespace dinic {
const int maxn = 1e6, maxm = 1e6;
typedef int FlowType;
const FlowType inf_f = ~0U >> 1;

void Init(int n);
void AddEdge(int u, int v, FlowType cap, li id);
FlowType Solve(int s, int t);
vector<pair<li, FlowType>> Result(void);
} // namespace dinic

namespace dinic {
struct Edge {
  int v;
  li id;
  FlowType cap, cap0;
} edge[maxm << 1];

int n, m, s, t;
vector<int> g[maxn];

void Init(int _n) {
  n = _n, m = 0;
  for (int i = 0; i < n; ++i)
    g[i].clear();
}

void AddEdge(int u, int v, FlowType c, li id = -1) {
  g[u].push_back(m);
  edge[m++] = (Edge){v, id, c, c};
  g[v].push_back(m);
  edge[m++] = (Edge){u, id, 0, 0};
}

int iter[maxn], dist[maxn];

bool Bfs(void) {
  queue<int> que;
  que.push(s);
  FILL(dist, n, -1);
  dist[s] = 0;
  while (!que.empty()) {
    int u = que.front();
    que.pop();
    for (int i = 0; i < g[u].size(); ++i) {
      Edge &e = edge[g[u][i]];
      if (e.cap && dist[e.v] == -1) {
        dist[e.v] = dist[u] + 1;
        que.push(e.v);
      }
    }
  }
  return dist[t] >= 0;
}

FlowType Dfs(int u, FlowType f) {
  if (u == t)
    return f;
  FlowType sum = 0;
  for (int &i = iter[u]; i < g[u].size(); ++i) {
    Edge &e = edge[g[u][i]], &rev = edge[g[u][i] ^ 1];
    if (e.cap && dist[e.v] == dist[u] + 1) {
      FlowType res = Dfs(e.v, min(f - sum, e.cap));
      e.cap -= res;
      rev.cap += res;
      if ((sum += res) == f)
        break;
    }
  }
  return sum;
}

FlowType Solve(int _s, int _t) {
  s = _s, t = _t;
  FlowType ans = 0;
  while (Bfs()) {
    FILL(iter, n, 0);
    ans += Dfs(s, inf_f);
  }
  return ans;
}

vector<pair<li, FlowType>> Result(void) {
  vector<pair<li, FlowType>> ans;
  for (int u = 0; u < n; ++u) {
    for (int i = 0; i < g[u].size(); ++i) {
      Edge &e = edge[g[u][i]];
      if (e.cap < e.cap0 && e.id != -1) {
        ans.push_back(make_pair(e.id, e.cap0 - e.cap));
      }
    }
  }
  return ans;
}
} // namespace dinic

// ----------------------------------------

const int maxn = 1e5;
int n;
vector<int> E[maxn];
vector<int> F[maxn];

int match[maxn], par[maxn];
int A[maxn], B[maxn];

void NoSolution(void) {
  puts("-1");
  exit(0);
}

int main(void) {
  scanf("%d", &n);
  for (int i = 0; i < n - 1; ++i) {
    int c;
    scanf("%d", &c);
    while (c--) {
      int x;
      scanf("%d", &x);
      --x;
      E[i].push_back(x);
      F[x].push_back(i);
    }
  }

  // root = 0
  int L = 0, R = n, S = R + n - 1, T = S + 1, N = T + 1;
  dinic::Init(N);
  for (int i = 1; i < n; ++i) {
    dinic::AddEdge(S, L + i, 1, -1);
  }
  for (int i = 0; i < n - 1; ++i) {
    dinic::AddEdge(R + i, T, 1, -1);
  }
  for (int i = 1; i < n; ++i) {
    for (int j : F[i]) {
      dinic::AddEdge(L + i, R + j, 1, (li)i * n + j);
    }
  }
  int flow = dinic::Solve(S, T);
  if (flow < n - 1)
    NoSolution();

  vector<pair<li, int>> way = dinic::Result();
  for (pair<li, int> p : way) {
    int x = (int)(p.first / n), y = (int)(p.first % n);
    match[y] = x;
  }

  queue<int> que;
  que.push(0);
  FILL(par, n, -1);
  while (!que.empty()) {
    int u = que.front();
    que.pop();
    for (int j : F[u]) {
      int i = match[j];
      if (par[i] == -1) {
        par[i] = u;
        A[j] = i;
        B[j] = u;
        que.push(i);
      }
    }
  }
  for (int i = 1; i < n; ++i) {
    if (par[i] == -1)
      NoSolution();
  }
  for (int i = 0; i < n - 1; ++i) {
    printf("%d %d\n", A[i] + 1, B[i] + 1);
  }
  return 0;
}