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

#include <algorithm>
#include <cmath>
#include <complex>
#include <iomanip>
#include <iostream>
#include <queue>
#include <utility>
#include <vector>
using namespace std;

const double EPS = 1e-10;
const double INF = 1e12;
#define X real()
#define Y imag()
#define EQ(n, m) (abs((n) - (m)) < EPS)
typedef complex<double> P;
typedef vector<P> VP;
namespace std {
bool operator<(const P &a, const P &b) {
  return (a.X != b.X) ? a.X < b.X : a.Y < b.Y;
}
} // namespace std
bool ItsSP(P a, P b, P c) {
  return (abs(a - c) + abs(b - c) - abs(b - a)) < EPS;
}
void tri_search(P a, P b, P c, P d, double tg, double tw, VP &ret) {
  for (int i = 0; i < 2; i++) {
    P v[4] = {a, b, c, d};
    if (i == 0)
      reverse(v, v + 4);
    for (int j = 0; j < 2; j++) {
      P g = v[2 + j];
      P beg = v[0], end = v[1];
      for (int rep = 0; rep < 50; rep++) {
        P dir = end - beg;
        P mid1 = beg + dir * (1.0 / 3);
        P mid2 = beg + dir * (2.0 / 3);
        if (tg * abs(mid1 - v[0]) + tw * abs(g - mid1) >
            tg * abs(mid2 - v[0]) + tw * abs(g - mid2)) {
          beg = mid1;
        } else {
          end = mid2;
        }
      }
      ret.push_back(beg);
    }
  }
}

int main() {
  while (1) {
    int n;
    cin >> n;
    if (n == 0)
      break;

    VP v, poly;
    v.reserve(400);
    for (int i = 0; i < n; i++) {
      int x, y;
      cin >> x >> y;
      v.push_back(P(x, y));
      poly.push_back(P(x, y));
    }

    int tg, tw, sx, sy, gx, gy;
    cin >> tg >> tw;
    cin >> sx >> sy >> gx >> gy;
    P s(sx, sy), g(gx, gy);

    for (int i = 0; i < n; i++) {
      for (int j = i + 1; j < n; j++) {
        tri_search(v[i], v[(i + 1) % n], v[j], v[(j + 1) % n], tg, tw, v);
        tri_search(v[(i + 1) % n], v[i], v[(j + 1) % n], v[j], tg, tw, v);
      }
      tri_search(v[i], v[(i + 1) % n], s, s, tg, tw, v);
      tri_search(v[(i + 1) % n], v[i], s, s, tg, tw, v);
      tri_search(v[i], v[(i + 1) % n], g, g, tg, tw, v);
      tri_search(v[(i + 1) % n], v[i], g, g, tg, tw, v);
    }

    sort(v.begin(), v.end());
    v.erase(unique(v.begin(), v.end()), v.end());
    v.push_back(s);
    v.push_back(g);
    int sv = v.size();
    vector<vector<double>> adj(sv, vector<double>(sv, INF));
    for (int i = 0; i < sv; i++) {
      for (int j = i + 1; j < sv; j++) {
        bool onedge = false;
        for (int e = 0; e < n; e++) {
          if (ItsSP(poly[e], poly[(e + 1) % n], v[i]) &&
              ItsSP(poly[e], poly[(e + 1) % n], v[j])) {
            onedge = true;
            break;
          }
        }
        if (onedge) {
          adj[i][j] = adj[j][i] = tg * abs(v[i] - v[j]);
        } else {
          adj[i][j] = adj[j][i] = tw * abs(v[i] - v[j]);
        }
      }
    }

    double ans = INF;
    priority_queue<pair<double, int>> wait;
    vector<double> mincost(sv, INF);
    wait.push(make_pair(0, sv - 2));
    mincost[sv - 2] = 0;
    while (!wait.empty()) {
      int p = wait.top().second;
      double cost = -wait.top().first;
      wait.pop();
      if (cost > mincost[p])
        continue;
      if (p == sv - 1) {
        ans = cost;
        break;
      }
      for (int i = 0; i < sv; i++) {
        double newcost = cost + adj[p][i];
        if (newcost < mincost[i]) {
          wait.push(make_pair(-newcost, i));
          mincost[i] = newcost;
        }
      }
    }

    cout << fixed;
    cout << setprecision(12);
    cout << ans << endl;
  }
  return 0;
}

Error: TLE

Fixed submission:

#include <algorithm>
#include <cmath>
#include <complex>
#include <iomanip>
#include <iostream>
#include <queue>
#include <utility>
#include <vector>
using namespace std;

const double EPS = 1e-10;
const double INF = 1e12;
typedef complex<double> P;
typedef vector<P> VP;
bool ItsSP(P a, P b, P c) {
  return (abs(a - c) + abs(b - c) - abs(b - a)) < EPS;
}
void tri_search(P a, P b, P c, P d, double tg, double tw, VP &ret) {
  for (int i = 0; i < 2; i++) {
    P v[4] = {a, b, c, d};
    if (i == 0)
      reverse(v, v + 4);
    for (int j = 0; j < 2; j++) {
      P g = v[2 + j];
      P beg = v[0], end = v[1];
      for (int rep = 0; rep < 50; rep++) {
        P dir = end - beg;
        P mid1 = beg + dir * (1.0 / 3);
        P mid2 = beg + dir * (2.0 / 3);
        if (tg * abs(mid1 - v[0]) + tw * abs(g - mid1) >
            tg * abs(mid2 - v[0]) + tw * abs(g - mid2)) {
          beg = mid1;
        } else {
          end = mid2;
        }
      }
      ret.push_back(beg);
    }
  }
}

int main() {
  while (1) {
    int n;
    cin >> n;
    if (n == 0)
      break;

    VP v;
    v.reserve(400);
    for (int i = 0; i < n; i++) {
      int x, y;
      cin >> x >> y;
      v.push_back(P(x, y));
    }

    int tg, tw, sx, sy, gx, gy;
    cin >> tg >> tw;
    cin >> sx >> sy >> gx >> gy;
    P s(sx, sy), g(gx, gy);
    v.push_back(s);
    v.push_back(g);

    for (int i = 0; i < n; i++) {
      for (int j = i + 1; j < n; j++) {
        tri_search(v[i], v[(i + 1) % n], v[j], v[(j + 1) % n], tg, tw, v);
        tri_search(v[(i + 1) % n], v[i], v[(j + 1) % n], v[j], tg, tw, v);
      }
      tri_search(v[i], v[(i + 1) % n], s, s, tg, tw, v);
      tri_search(v[(i + 1) % n], v[i], s, s, tg, tw, v);
      tri_search(v[i], v[(i + 1) % n], g, g, tg, tw, v);
      tri_search(v[(i + 1) % n], v[i], g, g, tg, tw, v);
    }

    int sv = v.size();
    vector<vector<double>> adj(sv, vector<double>(sv, INF));
    for (int i = 0; i < sv; i++) {
      for (int j = i + 1; j < sv; j++) {
        bool onedge = false;
        ;
        for (int e = 0; e < n; e++) {
          if (ItsSP(v[e], v[(e + 1) % n], v[i]) &&
              ItsSP(v[e], v[(e + 1) % n], v[j])) {
            onedge = true;
            break;
          }
        }
        if (onedge) {
          adj[i][j] = adj[j][i] = tg * abs(v[i] - v[j]);
        } else {
          adj[i][j] = adj[j][i] = tw * abs(v[i] - v[j]);
        }
      }
    }

    double ans = INF;
    priority_queue<pair<double, int>> wait;
    vector<double> mincost(sv, INF);
    wait.push(make_pair(0, n));
    mincost[n] = 0;
    while (!wait.empty()) {
      int p = wait.top().second;
      double cost = -wait.top().first;
      wait.pop();
      if (cost > mincost[p])
        continue;
      if (p == n + 1) {
        ans = cost;
        break;
      }
      for (int i = 0; i < sv; i++) {
        double newcost = cost + adj[p][i];
        if (newcost < mincost[i]) {
          wait.push(make_pair(-newcost, i));
          mincost[i] = newcost;
        }
      }
    }

    cout << fixed;
    cout << setprecision(10);
    cout << ans << endl;
  }
  return 0;
}