Problem p01676 (C++) — buggy submission, verdict: Runtime Error

#include "bits/stdc++.h"
#include <unordered_map>
#include <unordered_set>
#pragma warning(disable : 4996)
using namespace std;
using ld = long double;
template <class T> using Table = vector<vector<T>>;
const ld eps = 1e-9;

// < "D:\\D_Download\\Visual Studio
// 2015\\Projects\\programing_contest_c++\\Debug\\a.txt" > "D:\\D_Download\\Visual
// Studio 2015\\Projects\\programing_contest_c++\\Debug\\b.txt"

/* verified AOJ1327 One-Dimensional Cellular Automaton
~Matrix~
??????????°????????¨?????????§??????
vector iostream cmath cassert ??????
Matrix a(VV), b(VV);
?????????:a*b
????????????:l*a
???:a+b
???:a-b
??¢???:a.transport()
?????????:a.cofactor()
?????????:a.det()
a???i???j??????:a.get(i,j)???
a???i??????j?????????k?????£??\\:set(i,j,k)
????????????a[i][j] (a[i][j]=k)
a???x???:a.pow(x)
n*n?????¬??????E:Matrix(n)
m*n 0??????:Matrix(m,n)
m*n ??¨????´????p?????????:Matrix(m,n,p)
Row???row??§????????????(m*1??????):Matrix(row)
**(??´??°??????)**
????§????:a.triangulate()
?????????:a.rank()
?????????:a.inverse()
//(????????????a.det()?????????a.pre_inverse()??§?±??????? ??´??°???)
??¬??????????¶???????:a.rowReduction()
//??£???????¬?????¨????????§£??????
***
*/

#include <cassert>
#include <cmath>
#include <iostream>
#include <vector>
using namespace std;

typedef ld Elem;
typedef vector<Elem> Row;
typedef vector<Row> VV;

typedef long double ld;
const ld EPS = 1e-11;

const bool isZero(const Elem e) { return abs(e) < EPS; }

struct Matrix {
  VV matrix;
  int n, m;

  Matrix(const VV &matrix_);
  explicit Matrix(int n_);
  explicit Matrix(const Row &row);
  Matrix(int m_, int n_);
  Matrix(int m_, int n_, Elem e);

  const Elem get(const int i, const int j) const;
  void set(const int x, const int y, const Elem k);

  const Matrix operator+(const Matrix &rhs) const;
  const Matrix operator*(const Matrix &rhs) const;
  const Matrix operator-(const Matrix &rhs) const;
  Matrix &operator+=(const Matrix &rhs);
  Matrix &operator*=(const Matrix &rhs);
  Matrix &operator-=(const Matrix &rhs);

  Row &operator[](const int x);

  const Matrix transport() const;
  const Matrix pow(int x) const;
  const Matrix cofactor(int x, int y) const;
  const Elem det() const;

  const Matrix triangulate() const;
  const int rank() const;

  //?????????????????¨????????°???(?????????)*(?????????)?????????
  // A:matrix,return det A * A^-1
  const Matrix pre_inverse() const;
  const Matrix inverse() const;
  const Matrix rowReduction() const;
};

const Matrix operator*(const Elem lambda, const Matrix &rhs) {
  Matrix tmp(rhs);
  for (int i = 0; i < rhs.m; i++)
    for (int j = 0; j < rhs.n; j++)
      tmp.set(i, j, tmp.get(i, j) * lambda);
  return tmp;
}

Matrix::Matrix(const VV &matrix_) : matrix(matrix_) {
  m = matrix_.size();
  if (m == 0)
    n = 0;
  else
    n = matrix_[0].size();
}
Matrix::Matrix(int n_) : m(n_), n(n_) {
  matrix = VV(n, Row(n, 0));
  for (int i = 0; i < n; ++i)
    set(i, i, 1);
}
Matrix::Matrix(const Row &row) : m(1), n(row.size()), matrix(VV(1, row)) {
  // size???m???vector<Elem>??????mx1???????????????
  (*this) = transport();
}
Matrix::Matrix(int m_, int n_) : m(m_), n(n_) { matrix = VV(m, Row(n, 0)); }
Matrix::Matrix(int m_, int n_, Elem e) : m(m_), n(n_) {
  matrix = VV(m, Row(n, e));
}

const Elem Matrix::get(const int i, const int j) const {
  if (0 <= i && i < m && 0 <= j && j < n)
    return matrix[i][j];

  cerr << "get(" << i << "," << j << ")is not exist." << endl;
  throw;
}
void Matrix::set(const int i, const int j, const Elem k) {
  if (0 <= i && i < m && 0 <= j && j < n) {
    *(matrix[i].begin() + j) = k;
    return;
  }
  cerr << "set(" << i << "," << j << ")is not exist." << endl;
  throw;
}

const Matrix Matrix::operator+(const Matrix &rhs) const {
  assert(m == rhs.m && n == rhs.n);

  Matrix tmp(m, n, 0);
  for (int i = 0; i < m; i++) {
    for (int j = 0; j < n; j++) {
      tmp.set(i, j, get(i, j) + rhs.get(i, j));
    }
  }
  return tmp;
}

const Matrix Matrix::operator*(const Matrix &rhs) const {
  assert(n == rhs.m);

  Matrix tmp(m, rhs.n, 0);
  Elem sum;
  for (int i = 0; i < m; i++)
    for (int j = 0; j < rhs.n; j++) {
      sum = 0;
      for (int k = 0; k < n; k++) {
        sum += get(i, k) * rhs.get(k, j);
      }
      tmp.set(i, j, sum);
    }
  return tmp;
}

const Matrix Matrix::operator-(const Matrix &rhs) const {
  return *this + ((Elem)-1 * rhs);
}

Matrix &Matrix::operator+=(const Matrix &rhs) { return *this = *this + rhs; }

Matrix &Matrix::operator*=(const Matrix &rhs) {
  return *this = *this * rhs;
  ;
}

Matrix &Matrix::operator-=(const Matrix &rhs) { return *this = *this - rhs; }

Row &Matrix::operator[](const int x) { return matrix[x]; }

const Matrix Matrix::transport() const {
  VV tmp;
  for (int i = 0; i < n; i++) {
    Row row;
    for (int j = 0; j < m; j++)
      row.push_back(get(j, i));
    tmp.push_back(row);
  }
  return tmp;
}

const Matrix Matrix::pow(int x) const {
  Matrix tmp(*this), e(m);
  for (int i = 1; i <= x; i <<= 1) {
    if ((x & i) > 0)
      e = e * tmp;
    tmp = tmp * tmp;
  }
  return e;
}

const Matrix Matrix::cofactor(int x, int y) const {
  VV tmp;
  for (int i = 0; i < m; i++) {
    if (x == i)
      continue;
    Row row;
    for (int j = 0; j < n; j++) {
      if (y == j)
        continue;
      row.push_back(get(i, j));
    }
    tmp.push_back(row);
  }
  return Matrix(tmp);
}

const Elem Matrix::det() const {
  assert(n == m);

  if (m == 1)
    return get(0, 0);
  Elem sum = 0;
  for (int i = 0; i < m; i++) {
    sum += ((i % 2 == 0 ? 1 : -1) * get(i, 0)) * Matrix(cofactor(i, 0)).det();
  }
  return sum;
}

const Matrix Matrix::triangulate() const {
  Matrix tmp(*this);
  Elem e;
  int p = 0;
  for (int i = 0; i < m && p < n; i++, p++) {
    if (isZero(tmp.get(i, p))) {
      tmp.set(i, p, 0);
      bool flag = true;
      for (int j = i + 1; j < m; j++)
        if (!isZero(tmp.get(j, p))) {
          for (int k = 0; k < n; k++)
            tmp.set(i, k, tmp.get(i, k) + tmp.get(j, k));
          // tmp[i].swap(tmp[j]);
          flag = false;
          break;
        }
      if (flag) {
        i--;
        continue;
      }
    }
    for (int j = i + 1; j < m; j++) {
      e = tmp.get(j, p) / tmp.get(i, p);
      for (int k = 0; k < n; k++)
        tmp.set(j, k, tmp.get(j, k) - tmp.get(i, k) * e);
    }
  }
  return tmp;
}

const int Matrix::rank() const {
  Matrix tmp(triangulate());
  for (int i = min(tmp.m - 1, tmp.n - 1); i >= 0; i--) {
    for (int j = tmp.n - 1; j >= i; j--)
      if (isZero(tmp.get(i, j)))
        continue;
      else
        return i + 1;
  }
  return 0;
}

const Matrix Matrix::pre_inverse() const {
  assert(m == n);

  Matrix tmp(m, n, 0);
  for (int i = 0; i < m; i++)
    for (int j = 0; j < n; j++)
      tmp.set(i, j, ((i + j) % 2 == 0 ? 1 : -1) * cofactor(i, j).det());
  return tmp.transport();
}

/*O(n!)????£?
const Matrix Matrix::inverse() const {
Matrix tmp(pre_inverse());
Elem e = det();
assert(!isZero(e));
tmp = 1 / e * tmp;
return tmp.transport();
}*/

const Matrix Matrix::inverse() const {
  assert(m == n);

  Matrix tmp(m, n * 2), tmp2(m, n);
  for (int i = 0; i < m; i++)
    for (int j = 0; j < n; j++)
      tmp.set(i, j, get(i, j));
  for (int i = 0; i < m; i++)
    tmp.set(i, i + n, 1);

  tmp = tmp.rowReduction();

  //?????????????????¨??????????????????????????§??????
  for (int i = 0; i < m; i++)
    assert(isZero(tmp.get(i, i) - 1));

  for (int i = 0; i < m; i++)
    for (int j = 0; j < n; j++)
      tmp2.set(i, j, tmp.get(i, j + n));

  return tmp2;
}

/*
a b c j
d e f k
g h i l

ax+by+cz=j;
dx+ey+fz=k;
gx+hy+iz=l;

|
V

1 0 0 x
0 1 0 y
0 0 1 z
???????????????
*/
const Matrix Matrix::rowReduction() const {
  Matrix tmp(*this);
  Elem e;
  int p = 0;
  for (int i = 0; i < m && p < n; i++, p++) {
    if (isZero(tmp.get(i, p))) {
      tmp.set(i, p, 0);
      bool flag = true;
      for (int j = i + 1; j < m; j++)
        if (!isZero(tmp.get(j, p))) {
          for (int k = 0; k < n; k++)
            tmp.set(i, k, tmp.get(i, k) + tmp.get(j, k));
          // tmp[i].swap(tmp[j]);
          flag = false;
          break;
        }
      if (flag) {
        i--;
        continue;
      }
    }
    e = 1 / tmp.get(i, p);
    tmp.set(i, p, 1);
    for (int k = i + 1; k < n; k++)
      tmp.set(i, k, tmp.get(i, k) * e);
    for (int j = 0; j < m; j++) {
      if (i == j)
        continue;
      e = tmp.get(j, p);
      for (int k = 0; k < n; k++)
        tmp.set(j, k, tmp.get(j, k) - tmp.get(i, k) * e);
    }
  }
  return tmp;
}

int main() {
  int N, M;
  cin >> N >> M;
  vector<vector<ld>> edges(N, vector<ld>(M));
  for (int i = 0; i < M; ++i) {
    int a, b;
    cin >> a >> b;
    a--;
    b--;
    edges[a][i]++;
    edges[b][i]--;
  }
  Matrix mat(edges);
  int num = mat.rank();
  int ans = M - num;
  cout << ans << endl;
  return 0;
}

Error: 0

Fixed submission:

#include "bits/stdc++.h"
#include <unordered_map>
#include <unordered_set>
#pragma warning(disable : 4996)
using namespace std;
using ld = long double;
template <class T> using Table = vector<vector<T>>;
const ld eps = 1e-9;

//// < "D:\\D_Download\\Visual Studio
///2015\\Projects\\programing_contest_c++\\Debug\\a.txt"

struct aa {
  int f;
  int t;
  int id;
};
int main() {
  int N, M;
  cin >> N >> M;
  vector<vector<pair<int, int>>> nums(N);
  vector<aa> ps;
  int id = 0;
  for (int i = 0; i < M; ++i) {
    int s, t;
    cin >> s >> t;
    s--;
    t--;
    nums[s].emplace_back(t, id);
    nums[t].emplace_back(s, id);
    ps.push_back(aa{s, t, id++});
  }
  for (int i = 0; i < N; ++i) {

    sort(nums[i].begin(), nums[i].end());
  }
  vector<int> oks(M, false);

  int now = 0;
  int ans = 0;
  while (1) {
    if (nums[ps[now].f].size() >= 2 && nums[ps[now].t].size() >= 2) {
      ans++;
      if (oks[now])
        continue;
      queue<int> que;
      que.push(now);
      while (!que.empty()) {
        int atop(que.front());
        que.pop();
        if (oks[atop])
          continue;
        oks[atop] = true;
        auto p = ps[atop];
        nums[p.f].erase(lower_bound(nums[p.f].begin(), nums[p.f].end(),
                                    make_pair(p.t, atop)));
        nums[p.t].erase(lower_bound(nums[p.t].begin(), nums[p.t].end(),
                                    make_pair(p.f, atop)));
        if (nums[p.f].size() == 1) {
          if (!oks[nums[p.f][0].second]) {

            que.push(nums[p.f][0].second);
          }
        }
        if (nums[p.t].size() == 1) {
          if (!oks[nums[p.t][0].second]) {

            que.push(nums[p.t][0].second);
          }
        }
      }
    } else {
      assert(oks[now]);
    }
    now++;
    if (now == ps.size())
      break;
  }
  cout << ans << endl;
  return 0;
}