Problem p00858 (C++) — buggy submission, verdict: Memory Limit Exceeded

#include <algorithm>
#include <cmath>
#include <cstdio>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <stack>
#include <string>
#include <vector>
using namespace std;

typedef long long ll;
typedef double ld;
typedef pair<short, short> P;
typedef pair<ll, P> P1;

#define fr first
#define sc second
#define mp make_pair
#define pb push_back
#define rep(i, x) for (int i = 0; i < x; i++)
#define rep1(i, x) for (int i = 1; i <= x; i++)
#define rrep(i, x) for (int i = x - 1; i >= 0; i--)
#define rrep1(i, x) for (int i = x; i > 0; i--)
#define sor(v) sort(v.begin(), v.end())
#define rev(s) reverse(s.begin(), s.end())
#define lb(vec, a) lower_bound(vec.begin(), vec.end(), a)
#define ub(vec, a) upper_bound(vec.begin(), vec.end(), a)
#define uniq(vec) vec.erase(unique(vec.begin(), vec.end()), vec.end())
#define mp1(a, b, c) P1(a, P(b, c))

const int INF = 1000000000;
const int dir_4[4][2] = {{1, 0}, {0, 1}, {-1, 0}, {0, -1}};
const int dir_8[8][2] = {{1, 0},  {1, 1},   {0, 1},  {-1, 1},
                         {-1, 0}, {-1, -1}, {0, -1}, {1, -1}};

int gcd(int x, int y) {
  if (y == 0)
    return x;
  return gcd(y, x % y);
}

vector<P> dir[1002][1002];
int f(int x, int y, int dx, int dy) {
  int ret = 0;
  rep(i, dir[x][y].size()) {
    P p = dir[x][y][i];
    int t = (p.fr - x) * dx + (p.sc - y) * dy;
    if (t > 0)
      ret |= 1;
    else if (t == 0)
      ret |= 3;
    else
      ret |= 2;
  }
  return ret;
}

ld cul_dist(ld x1, ld y1, ld x2, ld y2) {
  return sqrt((x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2));
}
static int n;
static int xs, ys, xg, yg;
static short cnt[1002][1002];
static vector<P> G[1002][1002];
static bool used[1002][1002];
static double dist[1002][1002];
static P pre[1002][1002];
priority_queue<pair<ld, P>, vector<pair<ld, P>>, greater<pair<ld, P>>> que;
int main() {
  while (1) {
    static int x1[202], y1[202], x2[202], y2[202];
    scanf("%d", &n);
    if (n == 0)
      break;
    scanf("%d%d%d%d", &xs, &ys, &xg, &yg);
    rep(i, n) { scanf("%d%d%d%d", &x1[i], &y1[i], &x2[i], &y2[i]); }

    rep(i, 1002) rep(j, 1002) cnt[i][j] = 0;
    rep(i, n) {
      if (x1[i] > x2[i] || (x1[i] == x2[i] && y1[i] > y2[i])) {
        swap(x1[i], x2[i]);
        swap(y1[i], y2[i]);
      }
      cnt[x1[i]][y1[i]]++;
      cnt[x2[i]][y2[i]]++;
    }

    rep(i, n) {
      int dx = x2[i] - x1[i];
      int dy = y2[i] - y1[i];
      int g = gcd(abs(dx), abs(dy));
      dx /= g;
      dy /= g;
      int locx = x1[i] + dx, locy = y1[i] + dy;
      while (!(locx == x2[i] && locy == y2[i])) {
        cnt[locx][locy]++;
        locx += dx;
        locy += dy;
      }
    }

    rep(i, 1002) rep(j, 1002) dir[i][j].clear();
    rep(i, n) {
      if (cnt[x1[i]][y1[i]] == 1) {
        dir[x2[i]][y2[i]].pb(P(x1[i], y1[i]));
      } else if (cnt[x2[i]][y2[i]] == 1) {
        dir[x1[i]][y1[i]].pb(P(x2[i], y2[i]));
      }
    }

    rep(i, 1002) rep(j, 1002) G[i][j].clear();
    rep(i, n) {
      if (cnt[x1[i]][y1[i]] == 1 || cnt[x2[i]][y2[i]] == 1)
        continue;
      int dx = x2[i] - x1[i];
      int dy = y2[i] - y1[i];
      int g = gcd(abs(dx), abs(dy));
      dx /= g;
      dy /= g;
      int prex1 = -1, prey1 = -1;
      int prex2 = -1, prey2 = -1;
      int locx = x1[i], locy = y1[i];
      while (locx <= x2[i] && !(dx == 0 && locy > y2[i])) {
        if (cnt[locx][locy] >= 1) {
          int t = f(locx, locy, dx, dy);
          if ((t & 1) == 0) {
            if (prex1 != -1)
              G[prex1][prey1].pb(P(locx, locy));
            prex1 = locx;
            prey1 = locy;
          } else {
            prex1 = -1;
            prey1 = -1;
          }
          if ((t & 2) == 0) {
            if (prex2 != -1)
              G[locx][locy].pb(P(prex2, prey2));
            prex2 = locx;
            prey2 = locy;
          } else {
            prex2 = -1;
            prey2 = -1;
          }
        }
        locx += dx;
        locy += dy;
      }
    }

    rep(i, 1002) rep(j, 1002) {
      used[i][j] = false;
      dist[i][j] = (ld)INF;
      pre[i][j] = P(-1, -1);
    }
    dist[xs][ys] = 0.0;
    que.push(pair<ld, P>(0.0, P(xs, ys)));
    while (!que.empty()) {
      pair<ld, P> p = que.top();
      que.pop();
      if (used[p.sc.fr][p.sc.sc])
        continue;
      used[p.sc.fr][p.sc.sc] = true;
      rep(i, G[p.sc.fr][p.sc.sc].size()) {
        P to = G[p.sc.fr][p.sc.sc][i];
        if (dist[to.fr][to.sc] >
            dist[p.sc.fr][p.sc.sc] + cul_dist(p.sc.fr, p.sc.sc, to.fr, to.sc)) {
          dist[to.fr][to.sc] =
              dist[p.sc.fr][p.sc.sc] + cul_dist(p.sc.fr, p.sc.sc, to.fr, to.sc);
          pre[to.fr][to.sc] = p.sc;
          que.push(pair<ld, P>(dist[to.fr][to.sc], to));
        }
      }
    }

    if (pre[xg][yg].fr == -1)
      cout << -1 << endl;
    else {
      vector<P> ans;
      P loc = P(xg, yg);
      ans.pb(loc);
      while (loc != P(xs, ys)) {
        loc = pre[loc.fr][loc.sc];
        ans.pb(loc);
      }
      rrep(i, ans.size()) {
        if (!(cnt[ans[i].fr][ans[i].sc] - dir[ans[i].fr][ans[i].sc].size() ==
              1))
          printf("%d %d\\n", ans[i].fr, ans[i].sc);
      }
      puts("0");
    }
  }
}

Error: MLE

Fixed submission:

#include <algorithm>
#include <cmath>
#include <cstdio>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <stack>
#include <string>
#include <vector>
using namespace std;

typedef long long ll;
typedef double ld;
typedef pair<int, int> P;
typedef pair<ll, P> P1;

#define fr first
#define sc second
#define mp make_pair
#define pb push_back
#define rep(i, x) for (int i = 0; i < x; i++)
#define rep1(i, x) for (int i = 1; i <= x; i++)
#define rrep(i, x) for (int i = x - 1; i >= 0; i--)
#define rrep1(i, x) for (int i = x; i > 0; i--)
#define sor(v) sort(v.begin(), v.end())
#define rev(s) reverse(s.begin(), s.end())
#define lb(vec, a) lower_bound(vec.begin(), vec.end(), a)
#define ub(vec, a) upper_bound(vec.begin(), vec.end(), a)
#define uniq(vec) vec.erase(unique(vec.begin(), vec.end()), vec.end())
#define mp1(a, b, c) P1(a, P(b, c))

const int INF = 1000000000;
const int dir_4[4][2] = {{1, 0}, {0, 1}, {-1, 0}, {0, -1}};
const int dir_8[8][2] = {{1, 0},  {1, 1},   {0, 1},  {-1, 1},
                         {-1, 0}, {-1, -1}, {0, -1}, {1, -1}};

int gcd(int x, int y) {
  if (y == 0)
    return x;
  return gcd(y, x % y);
}

vector<P> dir[1002][1002];
int f(int x, int y, int dx, int dy) {
  int ret = 0;
  rep(i, dir[x][y].size()) {
    P p = dir[x][y][i];
    int t = (p.fr - x) * dx + (p.sc - y) * dy;
    if (t > 0)
      ret |= 1;
    else if (t == 0)
      ret |= 3;
    else
      ret |= 2;
  }
  return ret;
}

ld cul_dist(ld x1, ld y1, ld x2, ld y2) {
  return sqrt((x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2));
}
static int n;
static int xs, ys, xg, yg;
static short cnt[1002][1002];
static vector<P> G[1002][1002];
static bool used[1002][1002];
static double dist[1002][1002];
static P pre[1002][1002];
priority_queue<pair<ld, P>, vector<pair<ld, P>>, greater<pair<ld, P>>> que;
int main() {
  while (1) {
    static int x1[202], y1[202], x2[202], y2[202];
    scanf("%d", &n);
    if (n == 0)
      break;
    scanf("%d%d%d%d", &xs, &ys, &xg, &yg);
    rep(i, n) { scanf("%d%d%d%d", &x1[i], &y1[i], &x2[i], &y2[i]); }

    rep(i, 1002) rep(j, 1002) cnt[i][j] = 0;
    rep(i, n) {
      if (x1[i] > x2[i] || (x1[i] == x2[i] && y1[i] > y2[i])) {
        swap(x1[i], x2[i]);
        swap(y1[i], y2[i]);
      }
      cnt[x1[i]][y1[i]]++;
      cnt[x2[i]][y2[i]]++;
    }

    rep(i, n) {
      int dx = x2[i] - x1[i];
      int dy = y2[i] - y1[i];
      int g = gcd(abs(dx), abs(dy));
      dx /= g;
      dy /= g;
      int locx = x1[i] + dx, locy = y1[i] + dy;
      while (!(locx == x2[i] && locy == y2[i])) {
        cnt[locx][locy]++;
        locx += dx;
        locy += dy;
      }
    }

    rep(i, 1002) rep(j, 1002) dir[i][j].clear();
    rep(i, n) {
      if (cnt[x1[i]][y1[i]] == 1) {
        dir[x2[i]][y2[i]].pb(P(x1[i], y1[i]));
      } else if (cnt[x2[i]][y2[i]] == 1) {
        dir[x1[i]][y1[i]].pb(P(x2[i], y2[i]));
      }
    }

    rep(i, 1002) rep(j, 1002) G[i][j].clear();
    rep(i, n) {
      if (cnt[x1[i]][y1[i]] == 1 || cnt[x2[i]][y2[i]] == 1)
        continue;
      int dx = x2[i] - x1[i];
      int dy = y2[i] - y1[i];
      int g = gcd(abs(dx), abs(dy));
      dx /= g;
      dy /= g;
      int prex1 = -1, prey1 = -1;
      int prex2 = -1, prey2 = -1;
      int locx = x1[i], locy = y1[i];
      while (locx <= x2[i] && !(dx == 0 && locy > y2[i])) {
        if (cnt[locx][locy] >= 1) {
          int t = f(locx, locy, dx, dy);
          if ((t & 1) == 0) {
            if (prex1 != -1)
              G[prex1][prey1].pb(P(locx, locy));
            prex1 = locx;
            prey1 = locy;
          } else {
            prex1 = -1;
            prey1 = -1;
          }
          if ((t & 2) == 0) {
            if (prex2 != -1)
              G[locx][locy].pb(P(prex2, prey2));
            prex2 = locx;
            prey2 = locy;
          } else {
            prex2 = -1;
            prey2 = -1;
          }
        }
        locx += dx;
        locy += dy;
      }
    }

    rep(i, 1002) rep(j, 1002) {
      used[i][j] = false;
      dist[i][j] = (ld)INF;
      pre[i][j] = P(-1, -1);
    }
    dist[xs][ys] = 0.0;
    que.push(pair<ld, P>(0.0, P(xs, ys)));
    while (!que.empty()) {
      pair<ld, P> p = que.top();
      que.pop();
      if (used[p.sc.fr][p.sc.sc])
        continue;
      used[p.sc.fr][p.sc.sc] = true;
      rep(i, G[p.sc.fr][p.sc.sc].size()) {
        P to = G[p.sc.fr][p.sc.sc][i];
        if (dist[to.fr][to.sc] >
            dist[p.sc.fr][p.sc.sc] + cul_dist(p.sc.fr, p.sc.sc, to.fr, to.sc)) {
          dist[to.fr][to.sc] =
              dist[p.sc.fr][p.sc.sc] + cul_dist(p.sc.fr, p.sc.sc, to.fr, to.sc);
          pre[to.fr][to.sc] = p.sc;
          que.push(pair<ld, P>(dist[to.fr][to.sc], to));
        }
      }
    }

    if (pre[xg][yg].fr == -1)
      cout << -1 << endl;
    else {
      vector<P> ans;
      P loc = P(xg, yg);
      ans.pb(loc);
      while (loc != P(xs, ys)) {
        loc = pre[loc.fr][loc.sc];
        ans.pb(loc);
      }
      rrep(i, ans.size()) {
        if (!(cnt[ans[i].fr][ans[i].sc] - dir[ans[i].fr][ans[i].sc].size() ==
              1))
          printf("%d %d\\n", ans[i].fr, ans[i].sc);
      }
      puts("0");
    }
  }
}