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

#include <iostream>
#include <queue>
#include <string>
#include <vector>

using namespace std;

struct edge {
  int cost;  // エッジのコスト
  int to[2]; // 接続先座標
};

struct node {
  vector<edge> link;
  int getid(int y, int x) {
    for (int i = 0; i < link.size(); i++) {
      if (link[i].to[0] == y && link[i].to[1] == x) {
        return i;
      }
    }
    return -1;
  }
  void pcost(int indx) {
    if (indx == -1)
      return;
    link[indx].cost++;
  }
  bool done;
  bool isInqueue;
  int x, y;
  int mincost;
  bool operator<(const node &right) const { return mincost > right.mincost; }
};

int limit(int p, int l, int u) {
  if (p < l)
    return l;
  if (p > u)
    return u;
  return p;
}

int main(void) {

  int W, H, N;
  int s_x, s_y, e_x, e_y;
  int d[4][2] = {{0, 1}, {0, -1}, {1, 0}, {-1, 0}};
  cin >> W >> H >> N >> s_x >> s_y >> e_x >> e_y;

  // グラフの作成
  node newnode;
  newnode.done = false;
  newnode.mincost = -1;
  newnode.isInqueue = false;
  vector<vector<node>> graph(H + 1, vector<node>(W + 1, newnode));

  for (int i = 0; i <= H; i++) {
    for (int j = 0; j <= W; j++) {
      graph[i][j].x = j;
      graph[i][j].y = i;
      for (int k = 0; k < 4; k++) {
        int dc[2] = {d[k][0] + i, d[k][1] + j};
        if (dc[0] < 0 || dc[0] > H || dc[1] < 0 || dc[1] > W)
          continue;
        edge e;
        e.cost = 0;
        e.to[0] = dc[0];
        e.to[1] = dc[1];
        graph[i][j].link.push_back(e);
      }
    }
  }

  // シュミレート　辺に重みをつける
  for (int i = 0; i < N; i++) {
    int x, y, t;
    string str;
    cin >> x >> y >> t >> str;

    int cx = x, cy = y;
    for (int j = 0; j < t; j++) {
      for (int k = 0; k < str.length(); k++) {
        switch (str[k]) {
        case 'R':
          if (cx == W - 1)
            continue;
          graph[cy][cx + 1].pcost(graph[cy][cx + 1].getid(cy + 1, cx + 1));
          graph[cy + 1][cx + 1].pcost(graph[cy + 1][cx + 1].getid(cy, cx + 1));
          cx++;
          break;
        case 'D':
          if (cy == H - 1)
            continue;
          graph[cy + 1][cx].pcost(graph[cy + 1][cx].getid(cy + 1, cx + 1));
          graph[cy + 1][cx + 1].pcost(graph[cy + 1][cx + 1].getid(cy + 1, cx));
          cy++;
          break;
        case 'L':
          if (cx == 0)
            continue;
          graph[cy][cx].pcost(graph[cy][cx].getid(cy + 1, cx));
          graph[cy + 1][cx].pcost(graph[cy + 1][cx].getid(cy, cx));
          cx--;
          break;
        case 'U':
          if (cy == 0)
            continue;
          graph[cy][cx].pcost(graph[cy][cx].getid(cy, cx + 1));
          graph[cy][cx + 1].pcost(graph[cy][cx + 1].getid(cy, cx));
          cy--;
          break;
        }

        cx = limit(cx, 0, W);
        cy = limit(cy, 0, H);
      }
    }
  }

  // ダイクストラ法を用いる
  // 優先度つきキューを用いた実装
  graph[s_y][s_x].mincost = 0;
  graph[s_y][s_x].isInqueue = true;
  priority_queue<node> q;
  q.push(graph[s_y][s_x]);

  while (!q.empty()) {
    node donenode = q.top();
    graph[donenode.y][donenode.x].isInqueue = false;
    q.pop();
    int indx[2] = {donenode.y, donenode.x};
    for (int i = 0; i < graph[indx[0]][indx[1]].link.size(); i++) {
      int to[2] = {graph[indx[0]][indx[1]].link[i].to[0],
                   graph[indx[0]][indx[1]].link[i].to[1]};
      int cost = graph[indx[0]][indx[1]].mincost +
                 graph[indx[0]][indx[1]].link[i].cost;
      if (graph[to[0]][to[1]].mincost < 0 ||
          cost < graph[to[0]][to[1]].mincost) {
        graph[to[0]][to[1]].mincost = cost;
        if (!graph[to[0]][to[1]].isInqueue) {
          graph[to[0]][to[1]].isInqueue = true;
          q.push(graph[to[0]][to[1]]);
        }
      }
    }
  }

  cout << graph[e_y][e_x].mincost << endl;

  return 0;
}

Error: TLE

Fixed submission:

#include <iostream>
#include <string>
#include <vector>

using namespace std;

struct edge {
  int cost;  // エッジのコスト
  int to[2]; // 接続先座標
};

struct node {
  vector<edge> link;
  int getid(int y, int x) {
    for (int i = 0; i < link.size(); i++) {
      if (link[i].to[0] == y && link[i].to[1] == x) {
        return i;
      }
    }
    return -1;
  }
  void pcost(int indx) {
    if (indx == -1)
      return;
    link[indx].cost++;
  }
  bool done;
  int mincost;
};

int limit(int p, int l, int u) {
  if (p < l)
    return l;
  if (p > u)
    return u;
  return p;
}

int main(void) {

  int W, H, N;
  int s_x, s_y, e_x, e_y;
  int d[4][2] = {{0, 1}, {0, -1}, {1, 0}, {-1, 0}};
  cin >> W >> H >> N >> s_x >> s_y >> e_x >> e_y;

  // グラフの作成
  node newnode;
  newnode.done = false;
  newnode.mincost = -1;
  vector<vector<node>> graph(H + 1, vector<node>(W + 1, newnode));

  for (int i = 0; i <= H; i++) {
    for (int j = 0; j <= W; j++) {
      for (int k = 0; k < 4; k++) {
        int dc[2] = {d[k][0] + i, d[k][1] + j};
        if (dc[0] < 0 || dc[0] > H || dc[1] < 0 || dc[1] > W)
          continue;
        edge e;
        e.cost = 0;
        e.to[0] = dc[0];
        e.to[1] = dc[1];
        graph[i][j].link.push_back(e);
      }
    }
  }

  // シュミレート　辺に重みをつける
  for (int i = 0; i < N; i++) {
    int x, y, t;
    string str;
    cin >> x >> y >> t >> str;

    int cx = x, cy = y;
    for (int j = 0; j < t; j++) {
      for (int k = 0; k < str.length(); k++) {
        switch (str[k]) {
        case 'R':
          if (cx == W - 1)
            continue;
          graph[cy][cx + 1].pcost(graph[cy][cx + 1].getid(cy + 1, cx + 1));
          graph[cy + 1][cx + 1].pcost(graph[cy + 1][cx + 1].getid(cy, cx + 1));
          cx++;
          break;
        case 'D':
          if (cy == H - 1)
            continue;
          graph[cy + 1][cx].pcost(graph[cy + 1][cx].getid(cy + 1, cx + 1));
          graph[cy + 1][cx + 1].pcost(graph[cy + 1][cx + 1].getid(cy + 1, cx));
          cy++;
          break;
        case 'L':
          if (cx == 0)
            continue;
          graph[cy][cx].pcost(graph[cy][cx].getid(cy + 1, cx));
          graph[cy + 1][cx].pcost(graph[cy + 1][cx].getid(cy, cx));
          cx--;
          break;
        case 'U':
          if (cy == 0)
            continue;
          graph[cy][cx].pcost(graph[cy][cx].getid(cy, cx + 1));
          graph[cy][cx + 1].pcost(graph[cy][cx + 1].getid(cy, cx));
          cy--;
          break;
        }

        cx = limit(cx, 0, W);
        cy = limit(cy, 0, H);
      }
    }
  }

  // ダイクストラ法を用いる
  graph[s_y][s_x].mincost = 0;

  int indx[2] = {-1, -1};
  int currentcost;

  while (true) {
    indx[0] = -1;
    indx[1] = -1;

    for (int i = 0; i <= H; i++) {
      for (int j = 0; j <= W; j++) {
        if (graph[i][j].done == true || graph[i][j].mincost < 0)
          continue;
        if (indx[0] == -1 || graph[i][j].mincost < currentcost) {
          currentcost = graph[i][j].mincost;
          indx[0] = i;
          indx[1] = j;
        }
      }
    }
    if (indx[0] == -1 && indx[1] == -1)
      break;
    graph[indx[0]][indx[1]].done = true;

    for (int i = 0; i < graph[indx[0]][indx[1]].link.size(); i++) {
      int to[2] = {graph[indx[0]][indx[1]].link[i].to[0],
                   graph[indx[0]][indx[1]].link[i].to[1]};
      int cost = graph[indx[0]][indx[1]].mincost +
                 graph[indx[0]][indx[1]].link[i].cost;
      if (graph[to[0]][to[1]].mincost < 0 ||
          cost < graph[to[0]][to[1]].mincost) {
        graph[to[0]][to[1]].mincost = cost;
      }
    }
  }
  /*
  for( int i = 0; i <= H; i++ ) {
          for( int j = 0; j <= W; j++ ) {
                  for( int k = 0; k < graph[i][j].link.size(); k++ ) {
                          printf("from%2d %2d :to %2d %2d cost %2d \\n", j, i,
  graph[i][j].link[k].to[1], graph[i][j].link[k].to[0],
  graph[i][j].link[k].cost);
                  }
          }
          cout << endl;
  }
  */

  cout << graph[e_y][e_x].mincost << endl;

  return 0;
}