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

#if 0

#endif
#include <algorithm>
#include <assert.h>
#include <complex>
#include <iostream>
#include <string>
#include <valarray>
#include <vector>
#define REP(i, n) for (int i = 0; i < n; i++)
using namespace std;
typedef long long ll;

int n;
struct Matrix {
  valarray<int> a;
  Matrix() : a(n * n) { a = 0; }
};
void showMatrix(const Matrix &Mat) {
  int j = 0;
  for (const auto &e : Mat.a) {
    if (j == n) {
      cout << endl;
      j = 0;
    }
    cout << e << " ";
    ++j;
  }
  cout << endl;
}
void showVec(const valarray<int> &vec) {
  cout << "(";
  for (auto e : vec)
    cout << " " << e << " ";
  cout << ")" << endl;
}
bool isEqual(const std::valarray<bool> &aResult) {
  bool equals = true;
  for (auto e : aResult) {
    equals &= e;
  }
  return equals;
}
Matrix multiply(const Matrix &A, const Matrix &B) {
  Matrix C;
  for (int i = 0; i < n; ++i)
    for (int j = 0; j < n; ++j) {
      C.a[i * n + j] =
          min((A.a[slice(i * n, n, 1)] * B.a[slice(j, n, n)]).sum(), 1);
    }
  return C;
}
Matrix unitMat() {
  Matrix unit;
  for (int i = 0; i < n; ++i)
    unit.a[i * n + i] = 1;
  return unit;
}
Matrix expMat(const Matrix &Mat, const ll num) {
  if (num == 0)
    return unitMat();
  else if (num == 1)
    return Mat;
  else if (num % 2)
    return multiply(Mat, expMat(Mat, num - 1));
  else
    return expMat(multiply(Mat, Mat), num / 2);
}
valarray<int> linearMap(const Matrix &M, const valarray<int> &vec) {
  valarray<int> R(n);
  for (int i = 0; i < n; ++i)
    R[i] = min((vec * M.a[slice(i * n, n, 1)]).sum(), 1);
  return R;
}
int main(void) {
  cin.tie(0);
  ios::sync_with_stdio(false);
#define ll int

  ll N, M, Z, s1, d1;

  while (cin >> N >> M >> Z) {
    if (N == 0 && M == 0 && Z == 0) {
      break;
    }
    n = M * 2;
    Matrix edgeToEdge;
    vector<pair<ll, ll>> edge;
    valarray<int> startEdge(M * 2), goalEdge(M * 2);
    for (int i = 0; i < M; ++i) {
      cin >> s1 >> d1;
      edge.push_back(make_pair(s1, d1));
    }
    for (int i = 0; i < M; ++i) {
      for (int j = 0; j < M; ++j) {
        if (edge[i].second == edge[j].first) {
          edgeToEdge.a[2 * j * 2 * M + 2 * i] = 1;
          edgeToEdge.a[(2 * i + 1) * 2 * M + 2 * j + 1] = 1;
        } else if (i != j && edge[i].first == edge[j].first) {
          edgeToEdge.a[2 * j * 2 * M + 2 * i + 1] = 1;
        } else if (i != j && edge[i].second == edge[j].second) {
          edgeToEdge.a[(2 * j + 1) * 2 * M + 2 * i] = 1;
        }
      }
      if (edge[i].second == N)
        goalEdge[2 * i] = 1;
      if (edge[i].second == 1)
        startEdge[2 * i + 1] = 1;
      if (edge[i].first == 1)
        startEdge[2 * i] = 1;
      if (edge[i].first == N)
        goalEdge[2 * i + 1] = 1;
    }

    Matrix totalMat = expMat(edgeToEdge, Z - 1);
    startEdge = linearMap(totalMat, startEdge);

    if ((startEdge * goalEdge).sum() > 0)
      cout << "yes" << endl;
    else
      cout << "no" << endl;
  }

  return 0;
}


Error: TLE

Fixed submission:

#if 0

#endif
#include <algorithm>
#include <assert.h>
#include <complex>
#include <iostream>
#include <string>
#include <valarray>
#include <vector>
#define REP(i, n) for (int i = 0; i < n; i++)
using namespace std;
typedef long long ll;

int n;
struct Matrix {
  valarray<int> a;
  Matrix() : a(n * n) { a = 0; }
};
void showMatrix(const Matrix &Mat) {
  int j = 0;
  for (const auto &e : Mat.a) {
    if (j == n) {
      cout << endl;
      j = 0;
    }
    cout << e << " ";
    ++j;
  }
  cout << endl;
}
void showVec(const valarray<int> &vec) {
  cout << "(";
  for (auto e : vec)
    cout << " " << e << " ";
  cout << ")" << endl;
}
bool isEqual(const std::valarray<bool> &aResult) {
  bool equals = true;
  for (auto e : aResult) {
    equals &= e;
  }
  return equals;
}

Matrix multiply(const Matrix &A, const Matrix &B) {
  Matrix C;
  for (int i = 0; i < n; ++i)
    for (int j = 0; j < n; ++j) {
      C.a[i * n + j] = (A.a[slice(i * n, n, 1)] * B.a[slice(j, n, n)]).sum();
    }
  return C;
}
Matrix unitMat() {
  Matrix unit;
  for (int i = 0; i < n; ++i)
    unit.a[i * n + i] = 1;
  return unit;
}
valarray<int> linearMap(const Matrix &M, const valarray<int> &vec) {
  valarray<int> R(n);
  for (int i = 0; i < n; ++i)
    R[i] = min((vec * M.a[slice(i * n, n, 1)]).sum(), 1);
  return R;
}
int main(void) {
  cin.tie(0);
  ios::sync_with_stdio(false);
#define ll int

  ll N, M, Z, s1, d1;

  while (cin >> N >> M >> Z) {
    if (N == 0 && M == 0 && Z == 0) {
      break;
    }
    n = M * 2;
    Matrix edgeToEdge;
    vector<pair<ll, ll>> edge;
    valarray<int> startEdge(M * 2), goalEdge(M * 2);
    for (int i = 0; i < M; ++i) {
      cin >> s1 >> d1;
      edge.push_back(make_pair(s1, d1));
    }
    for (int i = 0; i < M; ++i) {
      for (int j = 0; j < M; ++j) {
        if (edge[i].second == edge[j].first) {
          edgeToEdge.a[2 * j * 2 * M + 2 * i] = 1;
          edgeToEdge.a[(2 * i + 1) * 2 * M + 2 * j + 1] = 1;
        } else if (i != j && edge[i].first == edge[j].first) {
          edgeToEdge.a[2 * j * 2 * M + 2 * i + 1] = 1;
        } else if (i != j && edge[i].second == edge[j].second) {
          edgeToEdge.a[(2 * j + 1) * 2 * M + 2 * i] = 1;
        }
      }
      if (edge[i].second == N)
        goalEdge[2 * i] = 1;
      if (edge[i].second == 1)
        startEdge[2 * i + 1] = 1;
      if (edge[i].first == 1)
        startEdge[2 * i] = 1;
      if (edge[i].first == N)
        goalEdge[2 * i + 1] = 1;
    }

    Matrix totalMat = unitMat();
    for (int i = 0; i < Z - 1; ++i) {
      totalMat = multiply(totalMat, edgeToEdge);
    }
    startEdge = linearMap(totalMat, startEdge);

    if ((startEdge * goalEdge).sum() > 0)
      cout << "yes" << endl;
    else
      cout << "no" << endl;
  }

  return 0;
}