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

#include <bits/stdc++.h>

using namespace std;

#define REP(i, a, b) for (int i = a; i < (int)b; i++)
#define rep(i, n) REP(i, 0, n)

namespace tree {
struct union_find {
  static const int Max = 22;
  int par[Max], rank[Max], size[Max], compnum;

  union_find(int N) {
    compnum = N;
    for (int i = 0; i < N; i++) {
      par[i] = i;
      rank[i] = 0;
      size[i] = 1;
    }
  }

  int root(int x) { return par[x] == x ? x : par[x] = root(par[x]); }

  void unite(int x, int y) {
    x = root(x), y = root(y);
    if (x == y)
      return;
    if (rank[x] < rank[y]) {
      par[x] = y, size[y] += size[x];
    } else {
      par[y] = x, size[x] += size[y];
      if (rank[x] == rank[y])
        rank[x]++;
    }
    compnum--;
  }

  int operator[](int x) { return root(x); }
  void operator()(int x, int y) { return unite(x, y); }

  bool same(int x, int y) { return root(x) == root(y); }
  int size_of(int x) { return size[root(x)]; }
  int num_of_comps() { return compnum; }
};
} // namespace tree

int N, M;
unordered_map<string, int> idmap;
vector<string> langs;
bool speaks[23][33];

void input() {
  langs.clear();
  langs.resize(N);
  rep(i, N) {
    cin >> langs[i];
    idmap[langs[i]] = i;
  }
  memset(speaks, 0, sizeof speaks);
  rep(i, M) {
    int k;
    cin >> k;
    rep(_, k) {
      string s;
      cin >> s;
      speaks[i][idmap[s]] = 1;
    }
  }
}

bool next_combination(int &comb, int const BitSize) {
  // Assume: comb := (1 << K) - 1, K <= BitSize
  int x = comb & -comb, y = comb + x;
  comb = ((comb & ~y) / x >> 1) | y;
  return comb < 1 << BitSize;
}

void solve() {

  REP(K, 1, min(N + 1, 6)) {
    int comb = (1 << K) - 1;
    do {
      vector<int> uselangs;
      rep(i, N) {
        if (!(comb & 1 << i))
          continue;
        uselangs.push_back(i);
      }

      tree::union_find uf(M);

      rep(i, M) REP(j, i + 1, M) for (auto langid :
                                      uselangs) if (speaks[i][langid] &&
                                                    speaks[j][langid]) uf(i, j);

      if (uf.num_of_comps() == 1) {
        printf("%d\\n", (int)uselangs.size());
        for (auto e : uselangs)
          printf("%s\\n", langs[e].c_str());
        return;
      }
    } while (next_combination(comb, N));
  }
  puts("Impossible");
}

string to_binary(int x, int const LeastDigit = 0) {
  string ret;
  while (x)
    ret.push_back(x % 2 + '0'), x /= 2;
  for (int i = ret.size(); i < LeastDigit; i++)
    ret.push_back('0');
  reverse(ret.begin(), ret.end());
  return ret;
}

int main() {
  bool first = 0;
  for (; cin >> N >> M && (N | M);) {
    if (first)
      cout << endl;
    first = 1;
    input();
    solve();
  }

  return 0;
}

Error: TLE

Fixed submission:

#include <bits/stdc++.h>

using namespace std;

#define REP(i, a, b) for (int i = a; i < (int)b; i++)
#define rep(i, n) REP(i, 0, n)
#define all(c) (c).begin(), (c).end()
#define zero(a) memset(a, 0, sizeof a)
#define minus(a) memset(a, -1, sizeof a)
#define watch(a)                                                               \\
  { cout << #a << " = " << a << endl; }
template <class T1, class T2> inline bool minimize(T1 &a, T2 b) {
  return b < a && (a = b, 1);
}
template <class T1, class T2> inline bool maximize(T1 &a, T2 b) {
  return a < b && (a = b, 1);
}

typedef long long ll;
int const inf = 1 << 29;

namespace tree {
struct union_find {
  static const int Max = 22;
  int par[Max], rank[Max], size[Max], gnum;

  union_find(int N) {
    gnum = N;
    for (int i = 0; i < N; i++) {
      par[i] = i;
      rank[i] = 0;
      size[i] = 1;
    }
  }

  int root(int x) {
    if (par[x] == x)
      return x;
    return par[x] = root(par[x]);
  }

  void unite(int x, int y) {
    x = root(x);
    y = root(y);
    if (x == y)
      return;

    if (rank[x] < rank[y]) {
      par[x] = y;
      size[y] += size[x];
    } else {
      par[y] = x;
      size[x] += size[y];
      if (rank[x] == rank[y]) {
        rank[x]++;
      }
    }
    gnum--;
  }

  int operator[](int x) { return root(x); }
  void operator()(int x, int y) { return unite(x, y); }

  bool same(int x, int y) { return root(x) == root(y); }
  int size_of(int x) { return size[root(x)]; }
  int num_of_comps() { return gnum; }
};
} // namespace tree

int main() {

  bool first = 0;
  for (int N, M; cin >> N >> M && (N | M);) {
    if (first)
      cout << endl;
    first = 1;
    map<string, int> idmap;
    vector<string> langofid(N);
    int langcnt = 0;
    rep(i, N) {
      cin >> langofid[i];
      idmap[langofid[i]] = langcnt++;
    }

    vector<unordered_set<int>> vs(M);
    rep(i, M) {
      int k;
      cin >> k;
      rep(_, k) {
        string s;
        cin >> s;
        vs[i].insert(idmap[s]);
      }
    }

    REP(k, 1, min(N + 1, 6)) {
      int comb = (1 << k) - 1;
      while (comb < 1 << N) {
        int x = comb & -comb, y = comb + x;
        comb = ((comb & ~y) / x >> 1) | y;

        vector<int> uselangs;
        rep(i, N) {
          if (!(comb >> i & 1))
            continue;
          uselangs.push_back(i);
        }
        if (uselangs.empty())
          continue;

        tree::union_find uf(M);

        rep(i, M) REP(j, i + 1, M) {
          for (auto langid : uselangs) {
            if (vs[i].count(langid) && vs[j].count(langid)) {
              uf(i, j);
            }
          }
        }
        if (uf.num_of_comps() == 1) {
          cout << uselangs.size() << endl;
          for (auto e : uselangs) {
            printf("%s\\n", langofid[e].c_str());
          }
          goto next_tc;
        }
      }
    }
    puts("Impossible");
  next_tc:;
  }

  return 0;
}