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

#include <algorithm>
#include <bitset>
#include <cfloat>
#include <climits>
#include <cmath>
#include <cstdio>
#include <iomanip>
#include <iostream>
#include <list>
#include <map>
#include <numeric>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <vector>
using namespace std;

const double PI = acos(-1.0);
const double EPS = 1.0e-10;
const double INF = DBL_MAX / 1000;

int main() {
  int _tmp = 0;

  for (;;) {
    int n, x;
    cin >> n >> x;
    if (n == 0)
      return 0;

    int rStart, iStart, rGoal, iGoal;
    cin >> rStart >> iStart >> rGoal >> iGoal;

    vector<int> r1(x), i1(x), r2(x), i2(x);
    for (int j = 0; j < x; ++j)
      cin >> r1[j] >> i1[j] >> r2[j] >> i2[j];

    // スタート、ゴール、失われた辺が位置する多角形と、その前後の多角形のみに注目
    // また、一番中央にある多角形にも注目する
    map<int, int> rIndex;
    rIndex[1];
    for (int j = 0; j < 3; ++j) {
      rIndex[rStart - 1 + j];
      rIndex[rGoal - 1 + j];
    }
    for (int j = 0; j < x; ++j) {
      for (int k = 0; k < 3; ++k) {
        rIndex[r1[j] - 1 + k];
        rIndex[r2[j] - 1 + k];
      }
    }
    if (rIndex.begin()->first == 0)
      rIndex.erase(rIndex.begin());

    int m = 0;        // 注目する多角形の数
    vector<int> rPos; // 注目する多角形の位置
    for (map<int, int>::iterator it = rIndex.begin(); it != rIndex.end();
         ++it) {
      it->second = m;
      ++m;
      rPos.push_back(it->first);
    }

    set<pair<pair<int, int>, pair<int, int>>> damage;
    for (int j = 0; j < x; ++j) {
      damage.insert(make_pair(make_pair(rIndex[r1[j]], i1[j]),
                              make_pair(rIndex[r2[j]], i2[j])));
      damage.insert(make_pair(make_pair(rIndex[r2[j]], i2[j]),
                              make_pair(rIndex[r1[j]], i1[j])));
    }

    vector<vector<double>> minDist(m, vector<double>(n + 1, INF));
    minDist[rIndex[rStart]][iStart] = 0.0;
    multimap<double, pair<int, int>> mm;
    mm.insert(make_pair(0.0, make_pair(rIndex[rStart], iStart)));

    for (;;) {
      double dist0 = mm.begin()->first;
      int r0 = mm.begin()->second.first;
      int i0 = mm.begin()->second.second;
      mm.erase(mm.begin());
      if (dist0 > minDist[r0][i0] + EPS)
        continue;

      if (r0 == rIndex[rGoal] && i0 == iGoal) {
        printf("%.10f\\n", dist0);
        break;
      }

      for (int j = 0; j < 4; ++j) {
        double dist = dist0;
        int r = r0;
        int i = i0;
        if (j % 2 == 0) {
          r = r - 1 + j;
          if (r == -1 || r == m)
            continue;
          dist += abs(rPos[r] - rPos[r0]);
        } else {
          i = (i - 3 + j + n) % n + 1;
          dist += rPos[r] * sin(PI / n) * 2.0;
        }

        if (damage.find(make_pair(make_pair(r0, i0), make_pair(r, i))) !=
            damage.end())
          continue;

        if (dist < minDist[r][i] - EPS) {
          minDist[r][i] = dist;
          mm.insert(make_pair(dist, make_pair(r, i)));
        }
      }
    }
  }
}

Error: TLE

Fixed submission:

#include <algorithm>
#include <bitset>
#include <cfloat>
#include <climits>
#include <cmath>
#include <cstdio>
#include <iomanip>
#include <iostream>
#include <list>
#include <map>
#include <numeric>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <vector>
using namespace std;

const double PI = acos(-1.0);
const double EPS = 1.0e-10;
const double INF = DBL_MAX / 1000;

int main() {
  for (;;) {
    int n, x;
    cin >> n >> x;
    if (n == 0)
      return 0;

    int rStart, iStart, rGoal, iGoal;
    cin >> rStart >> iStart >> rGoal >> iGoal;

    vector<int> r1(x), i1(x), r2(x), i2(x);
    for (int j = 0; j < x; ++j)
      cin >> r1[j] >> i1[j] >> r2[j] >> i2[j];

    // スタート、ゴール、失われた辺が位置する多角形と、その前後の多角形のみに注目
    map<int, int> rIndex;
    for (int j = 0; j < 3; ++j) {
      rIndex[rStart - 1 + j];
      rIndex[iStart - 1 + j];
      rIndex[rGoal - 1 + j];
      rIndex[iGoal - 1 + j];
    }
    for (int j = 0; j < x; ++j) {
      for (int k = 0; k < 3; ++k) {
        rIndex[r1[j] - 1 + k];
        rIndex[r2[j] - 1 + k];
      }
    }
    if (rIndex.begin()->first == 0)
      rIndex.erase(rIndex.begin());

    int m = 0;        // 注目する多角形の数
    vector<int> rPos; // 注目する多角形の位置
    for (map<int, int>::iterator it = rIndex.begin(); it != rIndex.end();
         ++it) {
      it->second = m;
      ++m;
      rPos.push_back(it->first);
    }

    set<pair<pair<int, int>, pair<int, int>>> damage;
    for (int j = 0; j < x; ++j) {
      damage.insert(make_pair(make_pair(rIndex[r1[j]], i1[j]),
                              make_pair(rIndex[r2[j]], i2[j])));
      damage.insert(make_pair(make_pair(rIndex[r2[j]], i2[j]),
                              make_pair(rIndex[r1[j]], i1[j])));
    }

    vector<vector<double>> minDist(m, vector<double>(n, INF));
    minDist[rIndex[rStart]][iStart] = 0.0;
    multimap<double, pair<int, int>> mm;
    mm.insert(make_pair(0.0, make_pair(rIndex[rStart], iStart)));

    for (;;) {
      double dist0 = mm.begin()->first;
      int r0 = mm.begin()->second.first;
      int i0 = mm.begin()->second.second;
      mm.erase(mm.begin());
      if (dist0 > minDist[r0][i0] + EPS)
        continue;

      if (r0 == rIndex[rGoal] && i0 == iGoal) {
        printf("%.10f\\n", dist0);
        break;
      }

      for (int j = 0; j < 4; ++j) {
        double dist = dist0;
        int r = r0;
        int i = i0;
        if (j % 2 == 0) {
          r = r - 1 + j;
          if (r == -1 || r == m)
            continue;
          dist += abs(rPos[r] - rPos[r0]);
        } else {
          i = (i - 2 + j + n) % n;
          dist += rPos[r] * sin(PI / n) * 2.0;
        }

        if (damage.find(make_pair(make_pair(r0, i0), make_pair(r, i))) !=
            damage.end())
          continue;

        if (dist < minDist[r][i] - EPS) {
          minDist[r][i] = dist;
          mm.insert(make_pair(dist, make_pair(r, i)));
        }
      }
    }
  }
}