Problem p03921 (C++)

Buggy submission (status: Runtime Error):
/*
オーダー
10**6	余裕を持って間に合う
10**7	おそらく間に合う	余裕を持って間に合う
10**8	非常にシンプルな処理でない限り厳しい	おそらく間に合う
10**9		非常にシンプルな処理でない限り厳しい
logn	:OK
n		:10^7
nlogn	:10^6
n**2	:10^4
n**3	:300
2**n	:20
n!		:10



// 各桁の和を計算する関数
int findSumOfDigits(int n) {
  int sum = 0;
  while (n > 0) { // n が 0 になるまで
    sum += n % 10;
    n /= 10;
  }
  return sum;
}

sort(a, a + N, greater<int>());  // a[0:N] を大きい順にソート

int num[110] = {0};  // バケット
for (int i = 0; i < N; ++i) {
    num[d[i]]++;  // d[i] が 1 個増える
}

map<string, int> mp; // 連想配列 map<キー型, 値型> オブジェクト名
for (int i = 0; i < N; ++i) {
    auto itr = mp.find(s[i]);        // s[i] が設定されているか？
    if(itr != mp.end() ) {
         mp[s[i]] += 1;
    }
    else {
         mp[s[i]] += 1 ;
    }
}
stack<int> s;	//intをデータとするスタックを用意
s.push(1);		//{} -> {1}
printf("%d\n", s.top());	// 3
s.pop();

queue<int> que;	//intをデータとするキューを用意
que.push(1);		//{} -> {1}
printf("%d\n", que.front());	// 1
que.pop();
*/

#include <algorithm>
#include <bitset>
#include <iostream>
#include <map>
#include <math.h>
#include <queue>
#include <set>
#include <stack>
#include <string.h>
#include <string>
#include <vector>

using namespace std;

// #define for(i,a,b) for (int i=(a);i<(b);++i)
typedef long long ll;
typedef pair<ll, ll> P;
#define REP(i, n) for (long long i = 0; i < (long long)(n); i++)
#define pb push_back // vectorに要素追加
#define INF (ll)1e18
// int
// // 各桁の和を計算する関数
// int findSumOfDigits(int n) {
//   int amari = 0;
//   int keta = 0;
//   while (n > 0) { // n が 0 になるまで
//     amari += n % 2;
//     if (keta%2==0)
//     n /= 10;
//   }
//   return sum;
// }

ll gcd(ll a, ll b) {
  if (b == 0)
    return a;
  return gcd(b, a % b);
}

// const ll MAX_N = 1e5;
// ll N;
// ll h[MAX_N];
// ll dp[MAX_N+1]; // メモ化テーブル

// // i番目以降の品物から重さの総和がj以下になるように選ぶ
// void rec(ll i){
// 	if (i==0) dp[i] = 0;
// 	else if (i==1) dp[i] = abs(h[1]-h[0]);
// 	else dp[i] = min(dp[i-1]+abs(h[i]-h[i-1]), dp[i-2]+abs(h[i]-h[i-2]));
// 	return;
// }
const ll MAX_N = 1e5;
ll N, M;
bool visited_h[MAX_N];   // 各頂点が通過済みか
bool visited_l[MAX_N];   // 各頂点が通過済みか
vector<ll> human[MAX_N]; // graph[人番号][言語番号]
vector<ll> lang[MAX_N];  // graph[言語番号][人番号]

// 現在位置(x)
void dfs(ll i, bool mode_h) {
  if (mode_h) {          // 人番号が入力
    visited_h[i] = true; // 今いるところをtrueに置き換える
    REP(j, human[i].size()) {
      ll target_l = human[i][j];
      if (visited_l[target_l] == false)
        dfs(target_l, false);
    }
  } else {
    visited_l[i] = true; // 今いるところをtrueに置き換える
    REP(j, lang[i].size()) {
      ll target_h = lang[i][j];
      if (visited_h[target_h] == false)
        dfs(target_h, true);
    }
  }
}

int main() {
  // 入力
  cin >> N >> M;
  REP(i, M) {
    ll K;
    cin >> K;
    REP(j, K) {
      ll L;
      cin >> L;
      L--;
      human[i].pb(L);
      lang[L].pb(i);
    }
  }

  // 解法
  REP(i, N) visited_h[i] = false; // 訪問済み判定初期化
  REP(i, M) visited_l[i] = false; // 訪問済み判定初期化
  dfs(0, true);                   // DFSで連結判定
  // REP(i,N) printf("%lld %lld\n", i, visited_h[i]);
  bool ans = true;
  REP(i, N) if (visited_h[i] == false) ans = false;

  // 出力
  if (ans)
    printf("YES\n");
  else
    printf("NO\n");
}


Fixed submission:
/*
オーダー
10**6	余裕を持って間に合う
10**7	おそらく間に合う	余裕を持って間に合う
10**8	非常にシンプルな処理でない限り厳しい	おそらく間に合う
10**9		非常にシンプルな処理でない限り厳しい
logn	:OK
n		:10^7
nlogn	:10^6
n**2	:10^4
n**3	:300
2**n	:20
n!		:10



// 各桁の和を計算する関数
int findSumOfDigits(int n) {
  int sum = 0;
  while (n > 0) { // n が 0 になるまで
    sum += n % 10;
    n /= 10;
  }
  return sum;
}

sort(a, a + N, greater<int>());  // a[0:N] を大きい順にソート

int num[110] = {0};  // バケット
for (int i = 0; i < N; ++i) {
    num[d[i]]++;  // d[i] が 1 個増える
}

map<string, int> mp; // 連想配列 map<キー型, 値型> オブジェクト名
for (int i = 0; i < N; ++i) {
    auto itr = mp.find(s[i]);        // s[i] が設定されているか？
    if(itr != mp.end() ) {
         mp[s[i]] += 1;
    }
    else {
         mp[s[i]] += 1 ;
    }
}
stack<int> s;	//intをデータとするスタックを用意
s.push(1);		//{} -> {1}
printf("%d\n", s.top());	// 3
s.pop();

queue<int> que;	//intをデータとするキューを用意
que.push(1);		//{} -> {1}
printf("%d\n", que.front());	// 1
que.pop();
*/

#include <algorithm>
#include <bitset>
#include <iostream>
#include <map>
#include <math.h>
#include <queue>
#include <set>
#include <stack>
#include <string.h>
#include <string>
#include <vector>

using namespace std;

// #define for(i,a,b) for (int i=(a);i<(b);++i)
typedef long long ll;
typedef pair<ll, ll> P;
#define REP(i, n) for (long long i = 0; i < (long long)(n); i++)
#define pb push_back // vectorに要素追加
#define INF (ll)1e18
// int
// // 各桁の和を計算する関数
// int findSumOfDigits(int n) {
//   int amari = 0;
//   int keta = 0;
//   while (n > 0) { // n が 0 になるまで
//     amari += n % 2;
//     if (keta%2==0)
//     n /= 10;
//   }
//   return sum;
// }

ll gcd(ll a, ll b) {
  if (b == 0)
    return a;
  return gcd(b, a % b);
}

// const ll MAX_N = 1e5;
// ll N;
// ll h[MAX_N];
// ll dp[MAX_N+1]; // メモ化テーブル

// // i番目以降の品物から重さの総和がj以下になるように選ぶ
// void rec(ll i){
// 	if (i==0) dp[i] = 0;
// 	else if (i==1) dp[i] = abs(h[1]-h[0]);
// 	else dp[i] = min(dp[i-1]+abs(h[i]-h[i-1]), dp[i-2]+abs(h[i]-h[i-2]));
// 	return;
// }
const ll MAX_N = 1e5;
ll N, M;
bool visited_h[MAX_N];   // 各頂点が通過済みか
bool visited_l[MAX_N];   // 各頂点が通過済みか
vector<ll> human[MAX_N]; // graph[人番号][言語番号]
vector<ll> lang[MAX_N];  // graph[言語番号][人番号]

// 現在位置(x)
void dfs(ll i, bool mode_h) {
  if (mode_h) {          // 人番号が入力
    visited_h[i] = true; // 今いるところをtrueに置き換える
    REP(j, human[i].size()) {
      ll target_l = human[i][j];
      if (visited_l[target_l] == false)
        dfs(target_l, false);
    }
  } else {
    visited_l[i] = true; // 今いるところをtrueに置き換える
    REP(j, lang[i].size()) {
      ll target_h = lang[i][j];
      if (visited_h[target_h] == false)
        dfs(target_h, true);
    }
  }
}

int main() {
  // 入力
  cin >> N >> M;
  REP(i, N) {
    ll K;
    cin >> K;
    REP(j, K) {
      ll L;
      cin >> L;
      L--;
      human[i].pb(L);
      lang[L].pb(i);
    }
  }

  // 解法
  REP(i, N) visited_h[i] = false; // 訪問済み判定初期化
  REP(i, M) visited_l[i] = false; // 訪問済み判定初期化
  dfs(0, true);                   // DFSで連結判定
  // REP(i,N) printf("%lld %lld\n", i, visited_h[i]);
  bool ans = true;
  REP(i, N) if (visited_h[i] == false) ans = false;

  // 出力
  if (ans)
    printf("YES\n");
  else
    printf("NO\n");
}