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

#include <bits/stdc++.h>
using namespace std;

using P = pair<int, int>;

const int MAX_V = 500 * 500;
const int INF = 1e8;

struct edge {
  int to, cost;
};
typedef pair<int, int> P; // first は最短距離、 second は頂点の番号

int V;
vector<edge> G[MAX_V];
int d[MAX_V];

void dijkstra(int s) {
  // greater<P> を指定することで first が小さい順に取り出せるようにする
  priority_queue<P, vector<P>, greater<P>> que;
  fill(d, d + V, INF);
  d[s] = 0;
  que.push(P(0, s));
  while (!que.empty()) {
    P p = que.top();
    que.pop();
    int v = p.second;
    if (d[v] < p.first)
      continue;
    for (int i = 0; i < G[v].size(); i++) {
      edge e = G[v][i];
      if (d[e.to] > d[v] + e.cost) {
        d[e.to] = d[v] + e.cost;
        que.push(P(d[e.to], e.to));
      }
    }
  }
}

vector<int> dx = {1, 0, -1, 0};
vector<int> dy = {0, 1, 0, -1};

void fill(int y, int x, int cur, vector<vector<int>> &T) {
  T[y][x] = cur;
  for (int i = 0; i < 4; i++) {
    int ny = y + dy[i];
    int nx = x + dx[i];
    if (T[ny][nx] == -1) {
      fill(ny, nx, cur, T);
    }
  }
}

// Generated by 1.1.7.1 https://github.com/kyuridenamida/atcoder-tools  (tips:
// You use the default template now. You can remove this line by using your
// custom template)
int main() {
  // Failed to predict input format
  int H, W, Ch, Cw, Dh, Dw;
  cin >> H >> W >> Ch >> Cw >> Dh >> Dw;
  vector<string> S(H + 2);
  S[0] = string(W + 2, '#');
  S[H + 1] = string(W + 2, '#');
  for (int i = 1; i <= H; i++) {
    cin >> S[i];
    S[i] = "#" + S[i] + "#";
  }

  vector<vector<int>> T(H + 2, vector<int>(W + 2));
  for (int i = 1; i <= H; i++) {
    for (int j = 1; j <= W; j++) {
      if (S[i][j] == '.') {
        T[i][j] = -1;
      }
    }
  }

  // for (int i = 0; i <= H + 1; i++) {
  //     cout << S[i] << endl;
  // }
  // cout << endl;

  int cur = 1;
  for (int i = 1; i <= H; i++) {
    for (int j = 1; j <= W; j++) {
      if (T[i][j] == -1) {
        fill(i, j, cur, T);
        cur++;
      }
    }
  }

  // int d[cur + 1][cur + 1];
  // memset(d, 0x3f, sizeof(d));

  // vector<edge> es;
  set<P> seen;
  for (int i = 1; i <= H; i++) {
    for (int j = 1; j <= W; j++) {
      int u = T[i][j];
      if (u == 0) {
        continue;
      }
      for (int dy = -2; dy <= 2; dy++) {
        for (int dx = -2; dx <= 2; dx++) {
          int ny = i + dy;
          int nx = j + dx;
          if (ny <= 0 || ny > H || nx <= 0 || nx > W) {
            continue;
          }
          int v = T[ny][nx];
          if (v == 0) {
            continue;
          }

          // if (u == v) {
          //     d[u][v] = 0;
          // } else {
          //     d[u][v] = d[v][u] = 1;
          // }
          if (seen.count(P(u, v))) {
            continue;
          }
          if (u == v) {
            continue;
          }
          G[u].push_back({v, 1});
          G[v].push_back({u, 1});
          seen.insert(P(u, v));
          seen.insert(P(v, u));
        }
      }
    }
  }

  V = cur;
  dijkstra(T[Ch][Cw]);
  int ans = d[T[Dh][Dw]];
  if (ans == INF) {
    cout << -1 << endl;
  } else {
    cout << ans << endl;
  }

  // for (int i = 1; i <= H; i++) {
  //     for (int j = 1; j <= W; j++) {
  //         printf("%c", T[i][j] + 0x20);
  //     }
  //     printf("\\n");
  // }

  // for (int i = 0; i < cur+1; i++) {
  //     for (int j = 0; j < cur+1; j++) {
  //         printf("%10d ", d[i][j]);
  //     }
  //     printf("\\n");
  // }

  // int V = cur + 1; //  頂点数
  // for (int k = 0; k < V; k++) {
  //     for (int i = 0; i < V; i++) {
  //         for (int j = 0; j < V; j++) d[i][j] = min(d[i][j], d[i][k] +
  //         d[k][j]);
  //     }
  // }

  // cout << T[Ch][Cw] << ", " << T[Dh][Dw] << endl;
  // for (int i = 0; i < cur+1; i++) {
  //     for (int j = 0; j < cur+1; j++) {
  //         printf("%9d ", d[i][j]);
  //     }
  //     printf("\\n");
  // }

  // int ans = d[T[Ch][Cw]][T[Dh][Dw]];
  // if (ans == 0x3f3f3f3f) {
  //     cout << -1 << endl;
  // } else {
  //     cout << ans << endl;
  // }
}


Error: TLE

Fixed submission:

#include <bits/stdc++.h>
using namespace std;

using P = pair<int, int>;

const int MAX_V = 500 * 500;
const int INF = 1e8;

//  頂点 from から頂点 to へのコスト cost の辺
struct edge {
  int from, to, cost;
};

int d[MAX_V]; //  最短距離
int V, E;     // V は頂点数、 E は辺数
// s 番目の頂点から各頂点への最短距離を求める
void shortest_path(int s, vector<edge> &es) {
  for (int i = 0; i < V; i++)
    d[i] = INF;
  d[s] = 0;
  while (true) {
    bool update = false;
    for (int i = 0; i < E; i++) {
      edge e = es[i];
      if (d[e.from] != INF && d[e.to] > d[e.from] + e.cost) {
        d[e.to] = d[e.from] + e.cost;
        update = true;
      }
    }
    if (!update)
      break;
  }
}

vector<int> dx = {1, 0, -1, 0};
vector<int> dy = {0, 1, 0, -1};

void fill(int y, int x, int cur, vector<vector<int>> &T) {
  T[y][x] = cur;
  for (int i = 0; i < 4; i++) {
    int ny = y + dy[i];
    int nx = x + dx[i];
    if (T[ny][nx] == -1) {
      fill(ny, nx, cur, T);
    }
  }
}

// Generated by 1.1.7.1 https://github.com/kyuridenamida/atcoder-tools  (tips:
// You use the default template now. You can remove this line by using your
// custom template)
int main() {
  // Failed to predict input format
  int H, W, Ch, Cw, Dh, Dw;
  cin >> H >> W >> Ch >> Cw >> Dh >> Dw;
  vector<string> S(H + 2);
  S[0] = string(W + 2, '#');
  S[H + 1] = string(W + 2, '#');
  for (int i = 1; i <= H; i++) {
    cin >> S[i];
    S[i] = "#" + S[i] + "#";
  }

  vector<vector<int>> T(H + 2, vector<int>(W + 2));
  for (int i = 1; i <= H; i++) {
    for (int j = 1; j <= W; j++) {
      if (S[i][j] == '.') {
        T[i][j] = -1;
      }
    }
  }

  // for (int i = 0; i <= H + 1; i++) {
  //     cout << S[i] << endl;
  // }
  // cout << endl;

  int cur = 1;
  for (int i = 1; i <= H; i++) {
    for (int j = 1; j <= W; j++) {
      if (T[i][j] == -1) {
        fill(i, j, cur, T);
        cur++;
      }
    }
  }

  // int d[cur + 1][cur + 1];
  // memset(d, 0x3f, sizeof(d));

  vector<edge> es;
  set<P> seen;
  for (int i = 1; i <= H; i++) {
    for (int j = 1; j <= W; j++) {
      int u = T[i][j];
      if (u == 0) {
        continue;
      }
      for (int dy = -2; dy <= 2; dy++) {
        for (int dx = -2; dx <= 2; dx++) {
          int ny = i + dy;
          int nx = j + dx;
          if (ny <= 0 || ny > H || nx <= 0 || nx > W) {
            continue;
          }
          int v = T[ny][nx];
          if (v == 0) {
            continue;
          }

          // if (u == v) {
          //     d[u][v] = 0;
          // } else {
          //     d[u][v] = d[v][u] = 1;
          // }
          if (seen.count(P(u, v))) {
            continue;
          }
          if (u == v) {
            continue;
          }
          es.push_back({u, v, 1});
          es.push_back({v, u, 1});
          seen.insert(P(u, v));
          seen.insert(P(v, u));
        }
      }
    }
  }

  E = es.size();
  V = cur;
  shortest_path(T[Ch][Cw], es);
  int ans = d[T[Dh][Dw]];
  if (ans == INF) {
    cout << -1 << endl;
  } else {
    cout << ans << endl;
  }

  // for (int i = 1; i <= H; i++) {
  //     for (int j = 1; j <= W; j++) {
  //         printf("%c", T[i][j] + 0x20);
  //     }
  //     printf("\\n");
  // }

  // for (int i = 0; i < cur+1; i++) {
  //     for (int j = 0; j < cur+1; j++) {
  //         printf("%10d ", d[i][j]);
  //     }
  //     printf("\\n");
  // }

  // int V = cur + 1; //  頂点数
  // for (int k = 0; k < V; k++) {
  //     for (int i = 0; i < V; i++) {
  //         for (int j = 0; j < V; j++) d[i][j] = min(d[i][j], d[i][k] +
  //         d[k][j]);
  //     }
  // }

  // cout << T[Ch][Cw] << ", " << T[Dh][Dw] << endl;
  // for (int i = 0; i < cur+1; i++) {
  //     for (int j = 0; j < cur+1; j++) {
  //         printf("%9d ", d[i][j]);
  //     }
  //     printf("\\n");
  // }

  // int ans = d[T[Ch][Cw]][T[Dh][Dw]];
  // if (ans == 0x3f3f3f3f) {
  //     cout << -1 << endl;
  // } else {
  //     cout << ans << endl;
  // }
}