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

#include <bits/stdc++.h>

using namespace std;

typedef vector<vector<int>> Mat;

typedef long long ll;

int N;
Mat operator*(const Mat &A, const Mat &B) {
  Mat res(N, vector<int>(N, 0));
  for (int i = 0; i < N; ++i) {
    for (int j = 0; j < N; ++j) {
      for (int k = 0; k < N; ++k) {
        res[i][j] += A[i][k] * B[k][j];
      }
      res[i][j] = res[i][j] ? 1 : 0;
    }
  }
  return res;
}

Mat pow(Mat A, ll n) {
  Mat res = A;
  for (int i = 0; i < N; ++i) {
    for (int j = 0; j < N; ++j) {
      res[i][j] = i == j ? 1 : 0;
    }
  }

  for (ll i = 1; i <= n; i <<= 1) {
    if (n & i) {
      res = res * A;
    }
    A = A * A;
  }
  return res;
}

struct Compress {
  map<int, int> m;
  int msz;

  Compress() : msz(0) {}

  int get(int id) { return m.find(id) != m.end() ? m[id] : -1; }
  void add(int id) { m[id] = msz++; }
};

typedef pair<int, int> P;
int main() {
  int M, Z;
  while (cin >> N >> M >> Z, N || M || Z) {
    Compress c;

    int n = N;

    vector<P> v;
    for (int i = 0; i < M; ++i) {
      int s, d;
      cin >> s >> d;
      --s, --d;
      v.push_back(P(s, d));
    }

    c.add(0);
    for (int i = 0; i < M; ++i) {
      int s = v[i].first, d = v[i].second;
      c.add(n * s + d);
      c.add(n * d + s);
    }

    N = c.msz;
    vector<vector<int>> m(N, vector<int>(N, 0));
    for (int i = 0; i < M; ++i) {
      int s = v[i].first, d = v[i].second;
      int sid = c.get(n * s + d), did = c.get(n * d + s);
      for (int j = 0; j < n; ++j) {
        if (j != d) {
          int id = c.get(n * s + j);
          if (id > -1)
            m[id][did] = 1;
        }
        if (j != s) {
          int id = c.get(n * d + j);
          if (id > -1)
            m[id][sid] = 1;
        }
      }
    }

    m = pow(m, Z);
    /*
                    for (int i = 0; i < N; ++i) {
                            for (int j = 0; j < N; ++j) {
                                    cout << m[i][j] << " ";
                            }
                            cout << endl;
                    }
                    cout << endl;
    */
    int ans = 0;
    for (int i = 0; i < n; ++i) {
      int id = c.get(n * (n - 1) + i);
      if (id > -1 && m[0][id])
        ans = 1;
    }
    if (ans) {
      cout << "yes" << endl;
    } else {
      cout << "no" << endl;
    }
  }
}

Error: TLE

Fixed submission:

#include <bits/stdc++.h>

using namespace std;

typedef vector<vector<int>> Mat;

typedef long long ll;

int N;
Mat operator*(const Mat &A, const Mat &B) {
  Mat res(N, vector<int>(N, 0));
  for (int i = 0; i < N; ++i) {
    for (int j = 0; j < N; ++j) {
      for (int k = 0; k < N; ++k) {
        res[i][j] += A[i][k] * B[k][j];
      }
      res[i][j] = res[i][j] ? 1 : 0;
    }
  }
  return res;
}

Mat pow(Mat A, ll n) {
  Mat res = A;
  for (int i = 0; i < N; ++i) {
    for (int j = 0; j < N; ++j) {
      res[i][j] = i == j ? 1 : 0;
    }
  }

  for (ll i = 1; i <= n; i <<= 1) {
    if (n & i) {
      res = res * A;
    }
    A = A * A;
  }
  return res;
}

int main() {
  int M, Z;
  while (cin >> N >> M >> Z, N || M || Z) {
    int n = N;
    N *= N;
    vector<vector<int>> m(N, vector<int>(N, 0));
    for (int i = 0; i < M; ++i) {
      int s, d;
      cin >> s >> d;
      --s, --d;
      for (int j = 0; j < n; ++j) {
        if (j != d)
          m[n * s + j][n * d + s] = 1;
        if (j != s)
          m[n * d + j][n * s + d] = 1;
      }
    }
    m = pow(m, Z);

    vector<int> e(N, 0);
    for (int i = n; i < N - n; ++i) {
      bool f = true;
      for (int j = 0; j < N; ++j) {
        if (m[i][j]) {
          f = false;
          break;
        }
      }
      if (f)
        e[i] = 1;
    }
    vector<int> s = e;
    for (int i = 0; i < N - 1; ++i) {
      s[i + 1] += s[i];
    }
    int nN = N - s[N - 1];
    Mat A(nN, vector<int>(nN));
    for (int i = 0; i < N; ++i) {
      if (e[i])
        continue;
      for (int j = 0; j < N; ++j) {
        if (e[j])
          continue;
        A[i - s[i]][j - s[j]] = m[i][j];
      }
    }
    N = nN, m = A;
    /*
                    for (int i = 0; i < N; ++i) {
                            for (int j = 0; j < N; ++j) {
                                    cout << m[i][j] << " ";
                            }
                            cout << endl;
                    }
                    cout << endl;
    */
    int ans = 0;
    for (int i = 0; i < n; ++i) {
      if (m[0][N - i - 1])
        ans = 1;
    }
    if (ans) {
      cout << "yes" << endl;
    } else {
      cout << "no" << endl;
    }
  }
}