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


/*****/

#include <bits/stdc++.h>

#pragma GCC target("avx")
#pragma GCC optimize("O3")
#pragma GCC optimize("unroll-loops")

using namespace std;
using pint = pair<int, int>;
template <class T> using vec = vector<T>;
template <class T> using vec2 = vector<vector<T>>;

constexpr int INF = numeric_limits<int>::max();

#define rep(i, n) for (int i = 0, i##_len = (n); i < i##_len; ++i)

template <class T> bool chmin(T &a, const T b) {
  if (a > b) {
    a = b;
    return true;
  }
  return false;
}

/*****/

void Main() {
  // 入力
  int h, w;
  cin >> h >> w;
  pint c, d;
  cin >> c.first >> c.second;
  c.first--;
  c.second--;
  cin >> d.first >> d.second;
  d.first--;
  d.second--;
  vec2<int> m(h, vec<int>(w));
  rep(y, h) {
    string s;
    cin >> s;
    rep(x, w) { m[y][x] = (s[x] == '#' ? -1 : INF); }
  }

  // 塗りつぶし
  // O(HW)
  vec2<int> f(h, vec<int>(w, -1));
  int fn = 0;
  rep(y, h) {
    rep(x, w) {
      if (m[y][x] == -1 || f[y][x] != -1)
        continue;

      queue<pint> q;
      q.push(make_pair(y, x));
      f[y][x] = fn;
      while (!q.empty()) {
        pint now = q.front();
        q.pop();
        int nowy = now.first;
        int nowx = now.second;

        if (0 <= nowy - 1 && m[nowy - 1][nowx] != -1 &&
            f[nowy - 1][nowx] == -1) {
          f[nowy - 1][nowx] = fn;
          q.push(make_pair(nowy - 1, nowx));
        }
        if (nowy + 1 < h && m[nowy + 1][nowx] != -1 &&
            f[nowy + 1][nowx] == -1) {
          f[nowy + 1][nowx] = fn;
          q.push(make_pair(nowy + 1, nowx));
        }
        if (0 <= nowx - 1 && m[nowy][nowx - 1] != -1 &&
            f[nowy][nowx - 1] == -1) {
          f[nowy][nowx - 1] = fn;
          q.push(make_pair(nowy, nowx - 1));
        }
        if (nowx + 1 < w && m[nowy][nowx + 1] != -1 &&
            f[nowy][nowx + 1] == -1) {
          f[nowy][nowx + 1] = fn;
          q.push(make_pair(nowy, nowx + 1));
        }
      }

      fn++;
    }
  }

  cerr << "fill end\\n";

  // グラフ化
  // O(HW)
  vec<set<int>> g(fn);
  rep(nowy, h) {
    rep(nowx, w) {
      if (m[nowy][nowx] == -1)
        continue;
      for (int y = nowy - 2; y <= nowy + 2; ++y) {
        if (0 > y || y >= h)
          continue;
        for (int x = nowx - 2; x <= nowx + 2; ++x) {
          if (0 > x || x >= w || m[y][x] == -1)
            continue;

          g[f[nowy][nowx]].insert(f[y][x]);
        }
      }
    }
  }

  cerr << "make end\\n";

  // 最短距離を見つける
  // たぶんO(WH)
  vec<int> min(fn, INF);
  queue<int> q;
  q.push(f[c.first][c.second]);
  min[f[c.first][c.second]] = 0;
  while (!q.empty()) {
    int now = q.front();
    q.pop();

    for (int to : g[now]) {
      if (chmin(min[to], min[now] + 1)) {
        q.push(to);
      }
    }
  }

  cout << (min[f[d.first][d.second]] == INF ? -1 : min[f[d.first][d.second]])
       << endl;
}

/*****/

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

  std::cout << std::fixed << std::setprecision(10);

  Main();
  std::cerr << flush;
  std::cout << flush;

  return 0;
}


Error: TLE

Fixed submission:


/*****/

#include <bits/stdc++.h>

using namespace std;
using ll = long long;
using pint = pair<int, int>;
template <class T> using vec = vector<T>;
template <class T> using vec2 = vector<vector<T>>;

constexpr int INF = numeric_limits<int>::max();

#define rep(i, n) for (int i = 0, i##_len = (n); i < i##_len; ++i)

template <class T> bool chmin(T &a, const T b) {
  if (a > b) {
    a = b;
    return true;
  }
  return false;
}

/*****/

void Main() {
  // 入力
  int h, w;
  cin >> h >> w;
  pint c, d;
  cin >> c.first >> c.second;
  c.first--;
  c.second--;
  cin >> d.first >> d.second;
  d.first--;
  d.second--;
  vec2<int> m(h, vec<int>(w));
  rep(y, h) {
    string s;
    cin >> s;
    rep(x, w) { m[y][x] = (s[x] == '#' ? -1 : INF); }
  }

  // 塗りつぶし
  // O(HW)
  vec2<int> f(h, vec<int>(w, -1));
  int fn = 0;
  rep(y, h) {
    rep(x, w) {
      if (m[y][x] == -1 || f[y][x] != -1)
        continue;

      queue<pint> q;
      q.push(make_pair(y, x));
      while (!q.empty()) {
        pint now = q.front();
        q.pop();
        int nowy = now.first;
        int nowx = now.second;
        f[nowy][nowx] = fn;

        if (0 <= nowy - 1 && m[nowy - 1][nowx] != -1 &&
            f[nowy - 1][nowx] == -1) {
          q.push(make_pair(nowy - 1, nowx));
        }
        if (nowy + 1 < h && m[nowy + 1][nowx] != -1 &&
            f[nowy + 1][nowx] == -1) {
          q.push(make_pair(nowy + 1, nowx));
        }
        if (0 <= nowx - 1 && m[nowy][nowx - 1] != -1 &&
            f[nowy][nowx - 1] == -1) {
          q.push(make_pair(nowy, nowx - 1));
        }
        if (nowx + 1 < w && m[nowy][nowx + 1] != -1 &&
            f[nowy][nowx + 1] == -1) {
          q.push(make_pair(nowy, nowx + 1));
        }
      }

      fn++;
    }
  }

  // グラフ化
  // O(HW)
  vec<set<int>> g(fn);
  rep(nowy, h) {
    rep(nowx, w) {
      if (m[nowy][nowx] == -1)
        continue;
      for (int y = nowy - 2; y <= nowy + 2; ++y) {
        if (0 > y || y >= h)
          continue;
        for (int x = nowx - 2; x <= nowx + 2; ++x) {
          if (0 > x || x >= w || m[y][x] == -1)
            continue;

          g[f[nowy][nowx]].insert(f[y][x]);
        }
      }
    }
  }

  // 最短距離を見つける
  // たぶんO(WH)
  vec<int> min(fn, INF);
  queue<int> q;
  q.push(f[c.first][c.second]);
  min[f[c.first][c.second]] = 0;
  while (!q.empty()) {
    int now = q.front();
    q.pop();

    for (int to : g[now]) {
      if (chmin(min[to], min[now] + 1)) {
        q.push(to);
      }
    }
  }

  cout << (min[f[d.first][d.second]] == INF ? -1 : min[f[d.first][d.second]])
       << endl;
}

/*****/

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

  std::cout << std::fixed << std::setprecision(10);

  Main();
  std::cerr << flush;
  std::cout << flush;

  return 0;
}