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

#define _USE_MATH_DEFINES
#define INF 0x3f3f3f3f
#include <algorithm>
#include <bitset>
#include <cctype>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <deque>
#include <iostream>
#include <limits>
#include <list>
#include <map>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <utility>

using namespace std;

typedef long long ll;
typedef pair<int, int> P;
typedef pair<int, P> PP;

int tx[] = {0, 1, 0, -1};
int ty[] = {-1, 0, 1, 0};

static const double EPS = 1e-8;

static const char RGB[] = {'R', 'G', 'B'};

class Data {
public:
  int cost;
  int pos;
  int used;
  int m1;
  int m2;
  Data(int _cost, int _pos, int _used, int _m1, int _m2)
      : cost(_cost), pos(_pos), used(_used), m1(_m1), m2(_m2) {}

  Data(int _cost, int _pos, int _used)
      : cost(_cost), pos(_pos), used(_used), m1(-1), m2(-1) {}
  bool operator<(const Data &d) const { return cost < d.cost; }

  bool operator>(const Data &d) const { return cost > d.cost; }
};

int path[101][101];
int idx[101][101];

int main() {
  int n, m;
  while (~scanf("%d %d", &n, &m)) {
    if (n == m && m == 0)
      break;

    map<PP, int> cost;
    memset(path, 0x3f, sizeof(path));
    vector<int> edge[101];

    for (int i = 0; i < m; i++) {
      int a, b, c;
      scanf("%d %d %d", &a, &b, &c);
      if (path[a][b] > c) {
        edge[a].push_back(b);
        edge[b].push_back(a);
        path[b][a] = path[a][b] = c;
        idx[b][a] = idx[a][b] = i;
      }
    }

    priority_queue<Data, vector<Data>, greater<Data>> que;
    cost[PP(1, P(-1, -1))] = 0;

    que.push(Data(0, 1, 0, -1, -1));

    int minv;
    while (!que.empty()) {
      Data d = que.top();
      que.pop();

      if (d.used != 1 && d.pos == n) {
        minv = d.cost;
        break;
      }

      for (int i = 0; i < edge[d.pos].size(); i++) {
        int to = edge[d.pos][i];
        if (to == d.pos)
          continue;
        if (path[d.pos][to] >= INF)
          continue;
        if (idx[d.pos][to] == d.m1)
          continue;

        if (d.used == 0) {
          // cost pos used path1 path2
          que.push(Data(d.cost, to, d.used + 1, idx[d.pos][to], -1));

          map<PP, int>::iterator it = cost.find(PP(to, P(-1, -1)));
          if (it != cost.end() && it->second > d.cost + path[d.pos][to]) {
            it->second = d.cost + path[d.pos][to];

            // cost pos used
            que.push(Data(d.cost + path[d.pos][to], to, d.used));
          } else if (it == cost.end()) {
            cost[PP(to, P(-1, -1))] = d.cost + path[d.pos][to];

            // cost pos used
            que.push(Data(d.cost + path[d.pos][to], to, d.used));
          }

        }

        else if (0 < d.used && d.used < 2) {
          map<PP, int>::iterator it = cost.find(
              PP(to, P(min(d.m1, idx[d.pos][to]), max(d.m1, idx[d.pos][to]))));
          if (it != cost.end() && it->second > d.cost) {
            it->second = d.cost;

            // cost pos used path1 path2
            que.push(Data(d.cost, to, d.used + 1, min(d.m1, idx[d.pos][to]),
                          max(d.m1, idx[d.pos][to])));
          } else if (it == cost.end()) {
            cost[PP(to, P(min(d.m1, idx[d.pos][to]),
                          max(d.m1, idx[d.pos][to])))] = d.cost;
            que.push(Data(d.cost, to, d.used + 1, min(d.m1, idx[d.pos][to]),
                          max(d.m1, idx[d.pos][to])));
          }
        } else {
          map<PP, int>::iterator it = cost.find(PP(to, P(d.m1, d.m2)));
          if (it != cost.end() && it->second > d.cost + path[d.pos][to]) {
            it->second = d.cost + path[d.pos][to];
            que.push(Data(d.cost + path[d.pos][to], to, d.used, d.m1, d.m2));
          } else if (it == cost.end()) {
            cost[PP(to, P(d.m1, d.m2))] = d.cost + path[d.pos][to];
            que.push(Data(d.cost + path[d.pos][to], to, d.used, d.m1, d.m2));
          }
        }
      }
    }

    // int minv = cost[PP(n,P(-1,-1))];
    // map<PP,int>::iterator it;
    // for(int m1=0;m1<m;m1++){
    //	for(int m2=m1+1;m2<m;m2++){
    //		if((it = cost.find(PP(n,P(m1,m2)))) != cost.end()){
    //			minv=min(it->second,minv);
    //		}
    //	}
    // }
    printf("%d\\n", minv);
  }
}

Error: TLE

Fixed submission:

#define _USE_MATH_DEFINES
#define INF 0x3f3f3f3f
#include <algorithm>
#include <bitset>
#include <cctype>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <deque>
#include <iostream>
#include <limits>
#include <list>
#include <map>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <utility>

using namespace std;

typedef long long ll;
typedef pair<int, int> P;
typedef pair<int, P> PP;

int tx[] = {0, 1, 0, -1};
int ty[] = {-1, 0, 1, 0};

static const double EPS = 1e-8;

static const char RGB[] = {'R', 'G', 'B'};

class Data {
public:
  int cost;
  int pos;
  int used;
  int m1;
  int m2;
  Data(int _cost, int _pos, int _used, int _m1, int _m2)
      : cost(_cost), pos(_pos), used(_used), m1(_m1), m2(_m2) {}

  Data(int _cost, int _pos, int _used)
      : cost(_cost), pos(_pos), used(_used), m1(-1), m2(-1) {}
  bool operator<(const Data &d) const { return cost < d.cost; }

  bool operator>(const Data &d) const { return cost > d.cost; }
};

int path[101][101];
int idx[101][101];

int main() {
  int n, m;
  while (~scanf("%d %d", &n, &m)) {
    if (n == m && m == 0)
      break;

    map<PP, int> cost;
    memset(path, 0x3f, sizeof(path));
    vector<int> edge[101];

    for (int i = 0; i < m; i++) {
      int a, b, c;
      scanf("%d %d %d", &a, &b, &c);
      if (path[a][b] > c) {
        edge[a].push_back(b);
        edge[b].push_back(a);
        path[b][a] = path[a][b] = c;
        idx[b][a] = idx[a][b] = i;
      }
    }

    priority_queue<Data, vector<Data>, greater<Data>> que;
    cost[PP(1, P(-1, -1))] = 0;

    que.push(Data(0, 1, 0, -1, -1));

    while (!que.empty()) {
      Data d = que.top();
      que.pop();

      for (int i = 0; i < edge[d.pos].size(); i++) {
        int to = edge[d.pos][i];
        if (to == d.pos)
          continue;
        if (path[d.pos][to] >= INF)
          continue;
        if (idx[d.pos][to] == d.m1)
          continue;

        if (d.used == 0) {
          // cost pos used path1 path2
          que.push(Data(d.cost, to, d.used + 1, idx[d.pos][to], -1));

          map<PP, int>::iterator it = cost.find(PP(to, P(-1, -1)));
          if (it != cost.end() && it->second > d.cost + path[d.pos][to]) {
            it->second = d.cost + path[d.pos][to];

            // cost pos used
            que.push(Data(d.cost + path[d.pos][to], to, d.used));
          } else if (it == cost.end()) {
            cost[PP(to, P(-1, -1))] = d.cost + path[d.pos][to];

            // cost pos used
            que.push(Data(d.cost + path[d.pos][to], to, d.used));
          }

        }

        else if (0 < d.used && d.used < 2) {
          map<PP, int>::iterator it = cost.find(
              PP(to, P(min(d.m1, idx[d.pos][to]), max(d.m1, idx[d.pos][to]))));
          if (it != cost.end() && it->second > d.cost) {
            it->second = d.cost;

            // cost pos used path1 path2
            que.push(Data(d.cost, to, d.used + 1, min(d.m1, idx[d.pos][to]),
                          max(d.m1, idx[d.pos][to])));
          } else if (it == cost.end()) {
            cost[PP(to, P(min(d.m1, idx[d.pos][to]),
                          max(d.m1, idx[d.pos][to])))] = d.cost;
            que.push(Data(d.cost, to, d.used + 1, min(d.m1, idx[d.pos][to]),
                          max(d.m1, idx[d.pos][to])));
          }
        } else {
          map<PP, int>::iterator it = cost.find(PP(to, P(d.m1, d.m2)));
          if (it != cost.end() && it->second > d.cost + path[d.pos][to]) {
            it->second = d.cost + path[d.pos][to];
            que.push(Data(d.cost + path[d.pos][to], to, d.used, d.m1, d.m2));
          } else if (it == cost.end()) {
            cost[PP(to, P(d.m1, d.m2))] = d.cost + path[d.pos][to];
            que.push(Data(d.cost + path[d.pos][to], to, d.used, d.m1, d.m2));
          }
        }
      }
    }

    int minv = cost[PP(n, P(-1, -1))];
    map<PP, int>::iterator it;
    for (int m1 = 0; m1 < m; m1++) {
      for (int m2 = m1 + 1; m2 < m; m2++) {
        if ((it = cost.find(PP(n, P(m1, m2)))) != cost.end()) {
          minv = min(it->second, minv);
        }
      }
    }
    printf("%d\\n", minv);
  }
}