Problem p03575 (C++)

Buggy submission (status: Runtime Error):
#include <bits/stdc++.h>
#include <cmath>
#include <numeric>
using namespace std;
#define rep(i, a, b) for (int64_t i = (a); i < (b); ++i) // a ≦ i < b
#define Rrep(i, a, b)                                                          \
  for (int64_t i = (a); i >= (b); --i) // reverse repeat. a から b まで減少．
#define ALL(a) (a).begin(), (a).end()
#define RALL(a) (a).rbegin(), (a).rend() // 逆イテレータ
#define INF 1000000000000000;
#define MOD 1000000007LL;
#define RANGE(a, b, c) (a).begin() + (b), (a).begin() + (c) // [b,c) イテレータ
typedef pair<int64_t, int64_t> PII;
typedef vector<int64_t> VI;
typedef vector<VI> VVI;
typedef vector<string> VS;
typedef vector<PII> VP;

vector<bool> seen;
void dfs(VVI &G, int v) {
  seen[v] = true;
  for (int nv : G[v]) {
    if (seen[nv])
      continue;
    dfs(G, nv);
  }
}

int main() {
  cin.tie(0);
  ios::sync_with_stdio(false);

  int N, M;
  cin >> N >> M;
  VI a(N), b(N);
  rep(i, 0, M) cin >> a[i] >> b[i];

  int ans = 0;
  rep(i, 0, M) {
    seen.assign(N + 1, false);
    VVI G(N + 1);
    rep(j, 0, M) if (i != j) {
      G[a[j]].push_back(b[j]);
      G[b[j]].push_back(a[j]);
    }
    dfs(G, 1);
    if (count(RANGE(seen, 1, N + 1), false))
      ++ans;
  }
  cout << ans << endl;
}
// 書いて考える
// 境界，出力文字列 チェック
// 可読性優先．高速化次点．
// まずは全探索，分割統治，次にDP
// 制限を見る．境界に注意．求めたい量の変域．
// 偶奇，逆から，ソート，出現回数，出現位置，DP， 余事象，包除
// データ構造． 問題の特徴量．単調性，二分探索
// 存在判定：構成方法，入力の特徴
// gcd, lcm ,素因数分解．
// 例外を十分に含む一般化．想像力の限界
// 小さい系から例示
// 代数的処理
// 始めは過剰に例示・場合分けしてもいい．各場合を確実に対処．
// 自明な例から処理，除外．
// 小数のときは，精度の設定する．doubel 変数に数値を入力するときは 123. とする．
// テストケース作成は数表あり


Fixed submission:
#include <bits/stdc++.h>
#include <cmath>
#include <numeric>
using namespace std;
#define rep(i, a, b) for (int64_t i = (a); i < (b); ++i) // a ≦ i < b
#define Rrep(i, a, b)                                                          \
  for (int64_t i = (a); i >= (b); --i) // reverse repeat. a から b まで減少．
#define ALL(a) (a).begin(), (a).end()
#define RALL(a) (a).rbegin(), (a).rend() // 逆イテレータ
#define INF 1000000000000000;
#define MOD 1000000007LL;
#define RANGE(a, b, c) (a).begin() + (b), (a).begin() + (c) // [b,c) イテレータ
typedef pair<int64_t, int64_t> PII;
typedef vector<int64_t> VI;
typedef vector<VI> VVI;
typedef vector<string> VS;
typedef vector<PII> VP;

vector<bool> seen;
void dfs(VVI &G, int v) {
  seen[v] = true;
  for (int nv : G[v]) {
    if (seen[nv])
      continue;
    dfs(G, nv);
  }
}

int main() {
  cin.tie(0);
  ios::sync_with_stdio(false);

  int N, M;
  cin >> N >> M;
  VI a(M), b(M);
  rep(i, 0, M) cin >> a[i] >> b[i];

  int ans = 0;
  rep(i, 0, M) {
    seen.assign(N + 1, false);
    VVI G(N + 1);
    rep(j, 0, M) if (i != j) {
      G[a[j]].push_back(b[j]);
      G[b[j]].push_back(a[j]);
    }
    dfs(G, 1);
    if (count(RANGE(seen, 1, N + 1), false))
      ++ans;
  }
  cout << ans << endl;
}
// 書いて考える
// 境界，出力文字列 チェック
// 可読性優先．高速化次点．
// まずは全探索，分割統治，次にDP
// 制限を見る．境界に注意．求めたい量の変域．
// 偶奇，逆から，ソート，出現回数，出現位置，DP， 余事象，包除
// データ構造． 問題の特徴量．単調性，二分探索
// 存在判定：構成方法，入力の特徴
// gcd, lcm ,素因数分解．
// 例外を十分に含む一般化．想像力の限界
// 小さい系から例示
// 代数的処理
// 始めは過剰に例示・場合分けしてもいい．各場合を確実に対処．
// 自明な例から処理，除外．
// 小数のときは，精度の設定する．doubel 変数に数値を入力するときは 123. とする．
// テストケース作成は数表あり