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

#include <bits/stdc++.h>

using namespace std;

#define int long long
#define all(v) begin(v), end(v)
#define rep(i, n) for (int i = 0; i < (int)(n); i++)
#define reps(i, s, n) for (int i = (int)(s); i < (int)(n); i++)

template <class T1, class T2> void chmin(T1 &a, T2 b) {
  if (a > b)
    a = b;
}
template <class T1, class T2> void chmax(T1 &a, T2 b) {
  if (a < b)
    a = b;
}

using pint = pair<int, int>;
using tint = tuple<int, int, int>;
using vint = vector<int>;

const int inf = 1LL << 55;
const int mod = 1e9 + 7;

struct UnionFind {
  vector<int> data;
  UnionFind() {}
  UnionFind(int sz) : data(sz, -1){};
  int size(int x) { return -data[find(x)]; }
  int find(int x) { return data[x] < 0 ? x : data[x] = find(data[x]); }
  bool same(int x, int y) { return find(x) == find(y); }
  int unite(int x, int y) {
    x = find(x), y = find(y);
    if (x != y) {
      if (data[x] < data[y])
        swap(x, y);
      data[x] += data[y];
      data[y] = x;
    }
    return -data[x];
  }
  void init(int sz) {
    data.clear();
    data.resize(sz, -1);
  }
};

UnionFind uf;

int N, M;
vector<string> lang;
map<string, int> mp;
map<string, int> group;
vector<int> vec;
vector<string> ans;

bool input() {
  cin >> N >> M;
  if (!N && !M)
    return false;

  lang.clear();
  mp.clear();
  rep(i, N) {
    string l;
    cin >> l;
    lang.push_back(l);
    mp[l] = i;
  }

  vec.clear();
  group.clear();
  rep(i, M) {
    int k;
    cin >> k;
    int bit = 0;
    rep(j, k) {
      string l;
      cin >> l;
      bit |= 1 << mp[l];
      group[l] |= 1 << i;
    }
    vec.push_back(bit);
  }

  return true;
}

void solve(int idx, int bit) {
  if (__builtin_popcount(bit) > 5)
    return;
  if (uf.size(N) == __builtin_popcount(bit) + M) {
    if (ans.empty() || __builtin_popcountll(bit) < ans.size()) {
      ans.clear();
      rep(i, N) if ((bit >> i) & 1) ans.push_back(lang[i]);
    }
  }

  reps(i, idx, N) {
    if ((bit >> i) & 1)
      continue;
    UnionFind tmp = uf;
    rep(j, M) if ((vec[j] >> i) & 1) uf.unite(i, N + j);
    solve(i + 1, bit | (1 << i));
    uf = tmp;
  }
}

signed main() {
  cin.tie(0);
  ios_base::sync_with_stdio(0);
  cout << fixed << setprecision(12);

  bool flag = false;
  while (input()) {
    if (flag)
      cout << endl;
    flag = true;

    ans.clear();
    uf.init(N + M);
    solve(0, 0);
    if (ans.size()) {
      cout << ans.size() << endl;
      for (string l : ans)
        cout << l << endl;
    } else {
      cout << "Impossible" << endl;
    }
  }
  return 0;
}

Error: TLE

Fixed submission:

#include <bits/stdc++.h>

using namespace std;

#define int long long
#define all(v) begin(v), end(v)
#define rep(i, n) for (int i = 0; i < (int)(n); i++)
#define reps(i, s, n) for (int i = (int)(s); i < (int)(n); i++)

template <class T1, class T2> void chmin(T1 &a, T2 b) {
  if (a > b)
    a = b;
}
template <class T1, class T2> void chmax(T1 &a, T2 b) {
  if (a < b)
    a = b;
}

using pint = pair<int, int>;
using tint = tuple<int, int, int>;
using vint = vector<int>;

const int inf = 1LL << 55;
const int mod = 1e9 + 7;

struct UF {
  vector<int> data;
  UF(int n) : data(n, -1) {}
  int find(int x) { return data[x] < 0 ? x : data[x] = find(data[x]); }
  int size(int x) { return -data[find(x)]; }
  bool same(int x, int y) { return find(x) == find(y); }
  bool unite(int x, int y) {
    x = find(x), y = find(y);
    if (x == y)
      return false;
    if (data[x] < data[y])
      swap(x, y);
    data[x] += data[y];
    data[y] = x;
    return true;
  }
  void init(int n) { data.assign(n, -1); }
};

signed main() {
  cin.tie(0);
  ios_base::sync_with_stdio(0);
  cout << fixed << setprecision(12);

  int N, M;
  bool flag = false;
  while (cin >> N >> M, N || M) {
    if (flag)
      cout << endl;
    flag = true;
    vector<string> lang(N);
    map<string, int> mp;
    rep(i, N) {
      cin >> lang[i];
      mp[lang[i]] = i;
    }
    vector<vector<int>> vec(M);
    rep(i, M) {
      int k;
      cin >> k;
      string l;
      rep(j, k) {
        cin >> l;
        vec[i].push_back(mp[l]);
      }
    }
    UF uf(N + M);
    bool ex = false;
    rep(bit, 1 << N) {
      uf.init(N + M);
      if (__builtin_popcountll(bit) > 5)
        continue;
      rep(i, M) {
        rep(j, vec[i].size()) {
          if ((bit >> vec[i][j]) & 1)
            uf.unite(vec[i][j], N + i);
        }
      }
      if (uf.size(N) == __builtin_popcountll(bit) + M) {
        ex = true;
        rep(i, N) {
          if ((bit >> i) & 1)
            cout << lang[i] << endl;
        }
        break;
      }
    }
    if (!ex)
      cout << "Impossible" << endl;
  }
  return 0;
}