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

#include <algorithm>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <fstream>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <stack>
#include <string>
#include <vector>
using namespace std;

#define REP(i, n) for (int i = 0; i < n; ++i)
#define FOR(i, a, b) for (int i = a; i <= b; ++i)
#define FORR(i, a, b) for (int i = a; i >= b; --i)
#define pi M_PI
#define EPS 1e-6

typedef long long ll;
typedef vector<int> VI;
typedef vector<ll> VL;
typedef vector<VI> VVI;
typedef pair<int, int> P;
typedef pair<ll, ll> PL;

int main() {
  int n, m = 32;
  ifstream ifs("in.txt");
  while (cin >> n && n) {
    int f[50][32] = {};
    REP(i, n) {
      int a;
      cin >> a;
      while (a--) {
        int x;
        cin >> x;
        f[i][x - 1] = 1;
      }
    }
    bool imp = 1;
    VL dp(n);
    REP(i, n) dp[i] = 1LL << i;
    REP(j, m) {
      ll x = 0;
      REP(i, n) {
        if (f[i][j])
          x |= dp[i];
      }
      REP(i, n) {
        if (f[i][j])
          dp[i] = x;
      }

      if (x == (1LL << n) - 1) {
        cout << j + 1 << endl;
        imp = 0;
        break;
      }
    }
    if (imp)
      cout << -1 << endl;
  }
  return 0;
}

Error: TLE

Fixed submission:

#include <algorithm>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <fstream>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <stack>
#include <string>
#include <vector>
using namespace std;

#define REP(i, n) for (int i = 0; i < n; ++i)
#define FOR(i, a, b) for (int i = a; i <= b; ++i)
#define FORR(i, a, b) for (int i = a; i >= b; --i)
#define pi M_PI
#define EPS 1e-6

typedef long long ll;
typedef vector<int> VI;
typedef vector<ll> VL;
typedef vector<VI> VVI;
typedef pair<int, int> P;
typedef pair<ll, ll> PL;

#define MAX_V 2000
#define INF 1e9

struct edge {
  int to, cap, rev;
};

vector<vector<edge>> G, Go;
bool used[MAX_V];

void add_edge(int from, int to, int cap) {
  G[from].push_back((edge){to, cap, (int)G[to].size()});
  G[to].push_back((edge){from, 0, (int)G[from].size() - 1});
}

int dfs(int v, int t, int f) {
  if (v == t)
    return f;
  used[v] = 1;
  REP(i, G[v].size()) {
    edge &e = G[v][i];
    if (!used[e.to] && e.cap > 0) {
      int d = dfs(e.to, t, min(f, e.cap));
      if (d > 0) {
        e.cap -= d;
        G[e.to][e.rev].cap += d;
        return d;
      }
    }
  }
  return 0;
}

int max_flow(int s, int t) {
  int flow = 0;
  while (1) {
    memset(used, 0, sizeof(used));
    int f = dfs(s, t, INF);
    if (f == 0)
      return flow;
    flow += f;
  }
}

int main() {
  int n, m = 30;
  while (cin >> n && n) {
    G.clear();
    G.resize(MAX_V);
    int s = 1600;
    REP(i, n) add_edge(s, i, 1);
    REP(j, m) REP(i, n) { add_edge(i + j * n, i + (j + 1) * n, m); }
    int f[50][30] = {};
    REP(i, n) {
      int a;
      cin >> a;
      while (a--) {
        int x;
        cin >> x;
        f[i][x - 1] = 1;
      }
    }
    REP(j, m) {
      REP(i, n) {
        if (f[i][j]) {
          add_edge(i + j * n, s + 1 + j, m);
          add_edge(s + 1 + j, i + (j + 1) * n, m);
        }
      }
    }
    Go = G;
    bool imp = 1;
    FOR(j, 1, m) {
      bool pos = 0;
      REP(i, n) {
        if (!f[i][j - 1])
          continue;
        if (max_flow(s, i + j * n) == n) {
          pos = 1;
        }
        G = Go;
      }
      if (pos) {
        cout << j << endl;
        imp = 0;
        break;
      }
    }
    if (imp)
      cout << -1 << endl;
  }
  return 0;
}