Problem p03921 (C++)

Buggy submission (status: Time Limit Exceeded):
#ifdef LOCAL111
#define _GLIBCXX_DEBUG
#else
#endif
#include <bits/stdc++.h>
const int INF = 1e9;
using namespace std;
template <typename T, typename U>
ostream &operator<<(ostream &os, const pair<T, U> &p) {
  cout << '(' << p.first << ' ' << p.second << ')';
  return os;
}

#define endl '\n'
#define ALL(a) (a).begin(), (a).end()
#define SZ(a) int((a).size())
#define FOR(i, a, b) for (int i = (a); i < (b); ++i)
#define RFOR(i, a, b) for (int i = (b)-1; i >= (a); i--)
#define REP(i, n) FOR(i, 0, n)
#define RREP(i, n) for (int i = (n)-1; i >= 0; i--)
#ifdef LOCAL111
#define DEBUG(x) cout << #x << ": " << (x) << endl
template <typename T> void dpite(T a, T b) {
  for (T ite = a; ite != b; ite++)
    cout << (ite == a ? "" : " ") << *ite;
  cout << endl;
}
#else
#define DEBUG(x) true
template <typename T> void dpite(T a, T b) { return; }
#endif
#define F first
#define S second
#define SNP string::npos
#define WRC(hoge) cout << "Case #" << (hoge) + 1 << ": "
template <typename T> void pite(T a, T b) {
  for (T ite = a; ite != b; ite++)
    cout << (ite == a ? "" : " ") << *ite;
  cout << endl;
}
template <typename T> bool chmax(T &a, T b) {
  if (a < b) {
    a = b;
    return true;
  }
  return false;
}
template <typename T> bool chmin(T &a, T b) {
  if (a > b) {
    a = b;
    return true;
  }
  return false;
}

typedef long long int LL;
typedef unsigned long long ULL;
typedef pair<int, int> P;
typedef pair<LL, LL> LP;

void ios_init() {
  // cout.setf(ios::fixed);
  // cout.precision(12);
#ifdef LOCAL111
  return;
#endif
  ios::sync_with_stdio(false);
  cin.tie(0);
}

// library
typedef long long cost_t;

class Edge {
public:
  int to;
  cost_t cost;

  Edge() {}

  Edge(int x, cost_t y) {
    to = x;
    cost = y;
  }

  bool operator<(const Edge &x) const {
    if (cost != x.cost)
      return cost < x.cost;
    return to < x.to;
  }

  bool operator>(const Edge &x) const {
    if (cost != x.cost)
      return cost > x.cost;
    return to > x.to;
  }
};

class Graph {
private:
  // const long long int INF = (long long)1e18;
  vector<vector<Edge>> v;
  int n;

public:
  Graph(int x) {
    n = x;
    v = vector<vector<Edge>>(x);
  }

  vector<Edge> &operator[](int x) { return v[x]; }

  const vector<Edge> &operator[](int x) const { return v[x]; }

  int size() const { return n; }

  void add_edge(int from, Edge e) { v[from].push_back(e); }

  void add_edge(int from, int to, cost_t cost) {
    add_edge(from, Edge(to, cost));
  }

  void add_uedge(int from, int to, cost_t cost) {
    add_edge(from, to, cost);
    add_edge(to, from, cost);
  }
};

vector<cost_t> dijkstra(int from, const Graph &v) {
  vector<cost_t> dist(v.size(), INF);
  priority_queue<Edge, vector<Edge>, greater<Edge>> que;
  que.push(Edge(from, 0));
  while (!que.empty()) {
    Edge e = que.top();
    que.pop();
    if (dist[e.to] == INF) {
      dist[e.to] = e.cost;
      for (auto to : v[e.to]) {
        if (dist[to.to] == INF)
          que.push(Edge(to.to, e.cost + to.cost));
      }
    }
  }
  return dist;
}

vector<cost_t> bellmanford(int from, const Graph &g) {
  vector<cost_t> res(g.size(), INF);
  res[from] = 0;
  bool conf = true;
  int cnt = 0;
  while (conf) {
    conf = false;
    for (int i = 0; i < g.size(); i++) {
      if (res[i] != INF)
        for (const auto &e : g[i]) {
          if (res[e.to] > res[i] + e.cost) {
            conf = true;
            res[e.to] = res[i] + e.cost;
          }
        }
    }
    if (cnt > g.size() + 5)
      return vector<cost_t>();
    cnt++;
  }
  return res;
}

Graph prim(const Graph g) {
  using T = tuple<cost_t, int, int>;
  priority_queue<T, vector<T>, greater<T>> qu;
  int n = g.size();
  assert(n != 0);
  vector<bool> added(n, false);
  qu.emplace(0, 0, 0);
  Graph res(n);
  while (!qu.empty()) {
    int from, to;
    cost_t cost;
    tie(cost, from, to) = qu.top();
    qu.pop();
    if (!added[to]) {
      added[to] = true;
      res.add_edge(from, to, cost);
      res.add_edge(to, from, cost);
      for (const auto &e : g[to]) {
        if (!added[e.to]) {
          qu.emplace(e.cost, to, e.to);
        }
      }
    }
  }
  return res;
}

vector<int> tree_getorder(const Graph &g, int root) {
  vector<int> res;
  function<void(int p, int pre)> func = [&](int p, int pre) {
    for (auto &e : g[p]) {
      if (e.to != pre) {
        func(e.to, p);
      }
    }
    res.push_back(p);
  };
  func(root, -1);
  return res;
}

vector<int> tree_getpar(const Graph &g, int root) {
  vector<int> par(g.size(), root);
  function<void(int p, int pre)> func = [&](int p, int pre) {
    par[p] = pre;
    for (auto &e : g[p]) {
      if (e.to != pre) {
        func(e.to, p);
      }
    }
  };
  func(root, root);
  return par;
}

// 未検証
vector<int> toposort(const Graph &g, int start) {
  int n = g.size();
  vector<int> res;
  res.reserve(n);
  vector<bool> used(n, false);
  function<void(int)> rec = [&](int p) {
    if (used[p])
      return;
    used[p] = true;
    for (auto &&e : g[p]) {
      rec(e.to);
    }
    res.push_back(p);
  };
  rec(start);
  return res;
}

// liblary

void vizGraph(const Graph &g, bool with_dir = false, bool with_cap = false) {
  ofstream ofs("./out.dot");
  if (with_dir)
    ofs << "graph graph_name {" << endl;
  else
    ofs << "digraph graph_name {" << endl;
  for (int i = 0; i < (int)g.size(); i++) {
    if (!g[i].size())
      continue;
    for (const auto &e : g[i]) {
      if (with_dir) {
        if (e.to > i)
          ofs << "    \"" << i << "\" -- \"" << e.to << '"';
      } else
        ofs << "    \"" << i << "\" -> \"" << e.to << '"';

      if (with_cap) {
        ofs << " [ label = \"" << (e.cost == INF ? "inf" : to_string(e.cost))
            << "\"];";
      }
      if (!with_dir or e.to > i)
        ofs << endl;
    }
  }
  ofs << "}" << endl;
  ofs.close();
  system("dot -T png out.dot > sample.png");
}

int main() {
  ios_init();
  int n, m;
  while (cin >> n >> m) {
    // assert(n < 2000 and m < 2000);
    Graph g(n + m);
    REP(i, n) {
      int k;
      cin >> k;
      REP(j, k) {
        int l;
        cin >> l;
        l--;
        g.add_uedge(i, l + n, -1);
      }
    }
    function<void(int, vector<bool> &)> dfs = [&](int p, vector<bool> &s) {
      if (s[p])
        return;
      s[p] = true;
      for (auto &&e : g[p]) {
        if (!s[e.to])
          dfs(e.to, s);
      }
      return;
    };
    // vizGraph(g);
    string ans = "YES";
    REP(i, n) {
      DEBUG(i);
      vector<bool> s(n + m, false);
      dfs(i, s);
      dpite(ALL(s));
      REP(j, n) {
        if (!s[j]) {
          ans = "NO";
          break;
        }
      }
    }
    cout << ans << endl;
  }
  return 0;
}


Fixed submission:
#ifdef LOCAL111
#define _GLIBCXX_DEBUG
#else
#endif
#include <bits/stdc++.h>
const int INF = 1e9;
using namespace std;
template <typename T, typename U>
ostream &operator<<(ostream &os, const pair<T, U> &p) {
  cout << '(' << p.first << ' ' << p.second << ')';
  return os;
}

#define endl '\n'
#define ALL(a) (a).begin(), (a).end()
#define SZ(a) int((a).size())
#define FOR(i, a, b) for (int i = (a); i < (b); ++i)
#define RFOR(i, a, b) for (int i = (b)-1; i >= (a); i--)
#define REP(i, n) FOR(i, 0, n)
#define RREP(i, n) for (int i = (n)-1; i >= 0; i--)
#ifdef LOCAL111
#define DEBUG(x) cout << #x << ": " << (x) << endl
template <typename T> void dpite(T a, T b) {
  for (T ite = a; ite != b; ite++)
    cout << (ite == a ? "" : " ") << *ite;
  cout << endl;
}
#else
#define DEBUG(x) true
template <typename T> void dpite(T a, T b) { return; }
#endif
#define F first
#define S second
#define SNP string::npos
#define WRC(hoge) cout << "Case #" << (hoge) + 1 << ": "
template <typename T> void pite(T a, T b) {
  for (T ite = a; ite != b; ite++)
    cout << (ite == a ? "" : " ") << *ite;
  cout << endl;
}
template <typename T> bool chmax(T &a, T b) {
  if (a < b) {
    a = b;
    return true;
  }
  return false;
}
template <typename T> bool chmin(T &a, T b) {
  if (a > b) {
    a = b;
    return true;
  }
  return false;
}

typedef long long int LL;
typedef unsigned long long ULL;
typedef pair<int, int> P;
typedef pair<LL, LL> LP;

void ios_init() {
  // cout.setf(ios::fixed);
  // cout.precision(12);
#ifdef LOCAL111
  return;
#endif
  ios::sync_with_stdio(false);
  cin.tie(0);
}

// library
typedef long long cost_t;

class Edge {
public:
  int to;
  cost_t cost;

  Edge() {}

  Edge(int x, cost_t y) {
    to = x;
    cost = y;
  }

  bool operator<(const Edge &x) const {
    if (cost != x.cost)
      return cost < x.cost;
    return to < x.to;
  }

  bool operator>(const Edge &x) const {
    if (cost != x.cost)
      return cost > x.cost;
    return to > x.to;
  }
};

class Graph {
private:
  // const long long int INF = (long long)1e18;
  vector<vector<Edge>> v;
  int n;

public:
  Graph(int x) {
    n = x;
    v = vector<vector<Edge>>(x);
  }

  vector<Edge> &operator[](int x) { return v[x]; }

  const vector<Edge> &operator[](int x) const { return v[x]; }

  int size() const { return n; }

  void add_edge(int from, Edge e) { v[from].push_back(e); }

  void add_edge(int from, int to, cost_t cost) {
    add_edge(from, Edge(to, cost));
  }

  void add_uedge(int from, int to, cost_t cost) {
    add_edge(from, to, cost);
    add_edge(to, from, cost);
  }
};

vector<cost_t> dijkstra(int from, const Graph &v) {
  vector<cost_t> dist(v.size(), INF);
  priority_queue<Edge, vector<Edge>, greater<Edge>> que;
  que.push(Edge(from, 0));
  while (!que.empty()) {
    Edge e = que.top();
    que.pop();
    if (dist[e.to] == INF) {
      dist[e.to] = e.cost;
      for (auto to : v[e.to]) {
        if (dist[to.to] == INF)
          que.push(Edge(to.to, e.cost + to.cost));
      }
    }
  }
  return dist;
}

vector<cost_t> bellmanford(int from, const Graph &g) {
  vector<cost_t> res(g.size(), INF);
  res[from] = 0;
  bool conf = true;
  int cnt = 0;
  while (conf) {
    conf = false;
    for (int i = 0; i < g.size(); i++) {
      if (res[i] != INF)
        for (const auto &e : g[i]) {
          if (res[e.to] > res[i] + e.cost) {
            conf = true;
            res[e.to] = res[i] + e.cost;
          }
        }
    }
    if (cnt > g.size() + 5)
      return vector<cost_t>();
    cnt++;
  }
  return res;
}

Graph prim(const Graph g) {
  using T = tuple<cost_t, int, int>;
  priority_queue<T, vector<T>, greater<T>> qu;
  int n = g.size();
  assert(n != 0);
  vector<bool> added(n, false);
  qu.emplace(0, 0, 0);
  Graph res(n);
  while (!qu.empty()) {
    int from, to;
    cost_t cost;
    tie(cost, from, to) = qu.top();
    qu.pop();
    if (!added[to]) {
      added[to] = true;
      res.add_edge(from, to, cost);
      res.add_edge(to, from, cost);
      for (const auto &e : g[to]) {
        if (!added[e.to]) {
          qu.emplace(e.cost, to, e.to);
        }
      }
    }
  }
  return res;
}

vector<int> tree_getorder(const Graph &g, int root) {
  vector<int> res;
  function<void(int p, int pre)> func = [&](int p, int pre) {
    for (auto &e : g[p]) {
      if (e.to != pre) {
        func(e.to, p);
      }
    }
    res.push_back(p);
  };
  func(root, -1);
  return res;
}

vector<int> tree_getpar(const Graph &g, int root) {
  vector<int> par(g.size(), root);
  function<void(int p, int pre)> func = [&](int p, int pre) {
    par[p] = pre;
    for (auto &e : g[p]) {
      if (e.to != pre) {
        func(e.to, p);
      }
    }
  };
  func(root, root);
  return par;
}

// 未検証
vector<int> toposort(const Graph &g, int start) {
  int n = g.size();
  vector<int> res;
  res.reserve(n);
  vector<bool> used(n, false);
  function<void(int)> rec = [&](int p) {
    if (used[p])
      return;
    used[p] = true;
    for (auto &&e : g[p]) {
      rec(e.to);
    }
    res.push_back(p);
  };
  rec(start);
  return res;
}

// liblary

void vizGraph(const Graph &g, bool with_dir = false, bool with_cap = false) {
  ofstream ofs("./out.dot");
  if (with_dir)
    ofs << "graph graph_name {" << endl;
  else
    ofs << "digraph graph_name {" << endl;
  for (int i = 0; i < (int)g.size(); i++) {
    if (!g[i].size())
      continue;
    for (const auto &e : g[i]) {
      if (with_dir) {
        if (e.to > i)
          ofs << "    \"" << i << "\" -- \"" << e.to << '"';
      } else
        ofs << "    \"" << i << "\" -> \"" << e.to << '"';

      if (with_cap) {
        ofs << " [ label = \"" << (e.cost == INF ? "inf" : to_string(e.cost))
            << "\"];";
      }
      if (!with_dir or e.to > i)
        ofs << endl;
    }
  }
  ofs << "}" << endl;
  ofs.close();
  system("dot -T png out.dot > sample.png");
}

int main() {
  ios_init();
  int n, m;
  while (cin >> n >> m) {
    // assert(n < 2000 and m < 2000);
    Graph g(n + m);
    REP(i, n) {
      int k;
      cin >> k;
      REP(j, k) {
        int l;
        cin >> l;
        l--;
        g.add_uedge(i, l + n, -1);
      }
    }
    function<void(int, vector<bool> &)> dfs = [&](int p, vector<bool> &s) {
      if (s[p])
        return;
      s[p] = true;
      for (auto &&e : g[p]) {
        if (!s[e.to])
          dfs(e.to, s);
      }
      return;
    };
    // vizGraph(g);
    string ans = "YES";
    // REP(i,n){
    // DEBUG(i);
    vector<bool> s(n + m, false);
    dfs(0, s);
    dpite(ALL(s));
    REP(j, n) {
      if (!s[j]) {
        ans = "NO";
        break;
      }
    }
    // }
    cout << ans << endl;
  }
  return 0;
}