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

#include <algorithm>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <deque>
#include <iostream>
#include <list>
#include <map>
#include <queue>
#include <set>
#include <stack>
#include <string>
#include <utility>
#include <vector>
#define INF (2000000000)
#define MOD (1000000007)
using namespace std;

typedef vector<int> VI;
typedef vector<int>::iterator VII;
typedef vector<double> VD;
typedef vector<double>::iterator VDI;
typedef pair<int, int> P;

typedef struct {
  int head[5000];
  VI to;
  VI next;
  VI cost;
} EDGE;

int N, K;
int C[5000], R[5000];
EDGE road;
EDGE taxi;
int d[5000];
int range[5000];

void SearchTaxi(int i, int now, int r) {
  if (r == 0)
    return;

  for (int e = road.head[now]; e != -1; e = road.next[e]) {
    taxi.next.push_back(taxi.head[i]);
    taxi.head[i] = taxi.next.size() - 1;
    taxi.to.push_back(road.to[e]);
    taxi.cost.push_back(C[i]);

    // int n = taxi.next.size() - 1;
    // printf("%d %d %d %d\\n", n, now, taxi.to[n], taxi.next[n], taxi.cost[n]);

    SearchTaxi(i, road.to[e], r - 1);
  }
}

void __SearchTaxi(int i) {
  memset(range, -1, sizeof(range));

  range[i] = R[i];

  while (true) {
    bool update = false;

    for (int i = 0; i < N; i++) {
      for (int e = road.head[i]; e != -1; e = road.next[e]) {
        if (range[road.to[e]] < range[i] - 1) {
          range[road.to[e]] = range[i] - 1;
          update = true;
        }
      }
    }

    if (!update)
      break;
  }

  for (int j = 0; j < N; j++) {
    if (range[j] != -1) {
      taxi.next.push_back(taxi.head[i]);
      taxi.head[i] = taxi.next.size() - 1;
      taxi.to.push_back(j);
      taxi.cost.push_back(C[i]);

      // int n = taxi.next.size() - 1;
      // printf("%d %d %d %d\\n", n, i, taxi.to[n], taxi.next[n], taxi.cost[n]);
    }
  }
}

void SearchMinCost() {
  for (int i = 1; i < N; i++) {
    d[i] = INF;
  }

  while (true) {
    bool update = false;

    for (int i = 0; i < N; i++) {
      for (int e = taxi.head[i]; e != -1; e = taxi.next[e]) {
        if (d[i] != INF && d[taxi.to[e]] > d[i] + taxi.cost[e]) {
          d[taxi.to[e]] = d[i] + taxi.cost[e];
          update = true;
        }
      }
    }

    if (!update)
      break;
  }
}

int main() {
  memset(road.head, -1, sizeof(road.head));
  memset(taxi.head, -1, sizeof(taxi.head));

  scanf("%d %d", &N, &K);

  for (int i = 0; i < N; i++) {
    scanf("%d %d", &C[i], &R[i]);
  }

  for (int i = 0; i < K; i++) {
    int a, b;
    scanf("%d %d", &a, &b);
    a--;
    b--;

    road.next.push_back(road.head[a]);
    road.head[a] = road.next.size() - 1;
    road.to.push_back(b);

    road.next.push_back(road.head[b]);
    road.head[b] = road.next.size() - 1;
    road.to.push_back(a);
  }

  for (int i = 0; i < N; i++) {
    // SearchTaxi(i, i, R[i]);
    __SearchTaxi(i);
  }

  SearchMinCost();

  printf("%d\\n", d[N - 1]);

  return 0;
}

Error: MLE

Fixed submission:

#include <algorithm>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <deque>
#include <iostream>
#include <list>
#include <map>
#include <queue>
#include <set>
#include <stack>
#include <string>
#include <utility>
#include <vector>
#define INF (2000000000)
#define MOD (1000000007)
using namespace std;

typedef vector<int> VI;
typedef vector<int>::iterator VII;
typedef vector<double> VD;
typedef vector<double>::iterator VDI;
typedef pair<int, int> P;

typedef struct {
  int head[5000];
  VI to;
  VI next;
  VI cost;
} EDGE;

int N, K;
int C[5000], R[5000];
EDGE road;
EDGE taxi;
int d[5000];
bool range[5000];

void SearchTaxi(int i, int now, int r) {
  if (r == 0)
    return;

  for (int e = road.head[now]; e != -1; e = road.next[e]) {
    taxi.next.push_back(taxi.head[i]);
    taxi.head[i] = taxi.next.size() - 1;
    taxi.to.push_back(road.to[e]);
    taxi.cost.push_back(C[i]);

    // int n = taxi.next.size() - 1;
    // printf("%d %d %d %d\\n", n, now, taxi.to[n], taxi.next[n], taxi.cost[n]);

    SearchTaxi(i, road.to[e], r - 1);
  }
}

void __SearchTaxi(int i) {
  memset(range, false, sizeof(range));

  queue<P> que;
  que.push(P(i, R[i]));
  while (que.size()) {
    P p = que.front();
    que.pop();

    range[p.first] = true;
    if (p.second > 0) {
      for (int e = road.head[p.first]; e != -1; e = road.next[e]) {
        que.push(P(road.to[e], p.second - 1));
      }
    }
  }

  range[i] = false;
  for (int j = 0; j < N; j++) {
    if (range[j]) {
      taxi.next.push_back(taxi.head[i]);
      taxi.head[i] = taxi.next.size() - 1;
      taxi.to.push_back(j);
      taxi.cost.push_back(C[i]);
    }
  }
}

void SearchMinCost() {
  for (int i = 1; i < N; i++) {
    d[i] = INF;
  }

  while (true) {
    bool update = false;

    for (int i = 0; i < N; i++) {
      for (int e = taxi.head[i]; e != -1; e = taxi.next[e]) {
        if (d[i] != INF && d[taxi.to[e]] > d[i] + taxi.cost[e]) {
          d[taxi.to[e]] = d[i] + taxi.cost[e];
          update = true;
        }
      }
    }

    if (!update)
      break;
  }
}

int main() {
  memset(road.head, -1, sizeof(road.head));
  memset(taxi.head, -1, sizeof(taxi.head));

  scanf("%d %d", &N, &K);

  for (int i = 0; i < N; i++) {
    scanf("%d %d", &C[i], &R[i]);
  }

  for (int i = 0; i < K; i++) {
    int a, b;
    scanf("%d %d", &a, &b);
    a--;
    b--;

    road.next.push_back(road.head[a]);
    road.head[a] = road.next.size() - 1;
    road.to.push_back(b);

    road.next.push_back(road.head[b]);
    road.head[b] = road.next.size() - 1;
    road.to.push_back(a);
  }

  for (int i = 0; i < N; i++) {
    // SearchTaxi(i, i, R[i]);
    __SearchTaxi(i);
  }

  SearchMinCost();

  printf("%d\\n", d[N - 1]);

  return 0;
}