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

// 2:00~

#include <cassert>
#include <cstdio>
#include <queue>

#define rep(i, n) for (int i = 0; i < (n); i++)

using namespace std;

const int INF = 1 << 29;

class edge {
public:
  int v, cost;
  edge(int v, int cost) : v(v), cost(cost) {}
};

int main() {
  for (int n, m, k; scanf("%d%d%d", &n, &m, &k), n;) {
    vector<edge> G[100];
    int d[100][100];
    rep(u, n) rep(v, n) d[u][v] = (u == v ? 0 : INF);
    rep(_, m) {
      int u, v, cost;
      scanf("%d%d%d", &u, &v, &cost);
      d[u][v] = d[v][u] = cost;
      G[u].push_back(edge(v, cost));
      G[v].push_back(edge(u, cost));
    }

    rep(w, n) rep(u, n) rep(v, n) d[u][v] = min(d[u][v], d[u][w] + d[w][v]);

    vector<int> D[100]; // 最短経路 DAG
    rep(u, n) rep(i, G[u].size()) {
      int v = G[u][i].v, cost = G[u][i].cost;
      if (d[0][u] + cost + d[v][n - 1] == d[0][n - 1])
        D[u].push_back(v);
    }

    double dp[100][100] = {}; // dp[u][v] := ( u->v 間の最短経路の個数 )
    // rep(u,n){
    // bool vis[100]={}; vis[u]=true;
    // dp[u][u]=1;
    // queue<int> Q; Q.push(u);
    // while(!Q.empty()){
    // int v=Q.front(); Q.pop();
    // rep(i,D[v].size()){
    // int w=D[v][i];
    // if(!vis[w]){
    // vis[w]=true;
    // Q.push(w);
    // }
    // dp[u][w]+=dp[u][v];
    // }
    // }
    // }
    rep(u, n) rep(i, G[u].size()) {
      int v = G[u][i].v, cost = G[u][i].cost;
      if (d[0][u] + cost + d[v][n - 1] == d[0][n - 1])
        dp[u][v] = 1;
    }
    rep(w, n) rep(u, n) rep(v, n) dp[u][v] += dp[u][w] * dp[w][v];

    rep(_, k) {
      int c;
      scanf("%d", &c);
      printf("%.9f\\n", dp[0][c] * dp[c][n - 1] / dp[0][n - 1]);
    }
    puts("");
  }

  return 0;
}

Error: MLE

Fixed submission:

// 2:00~

#include <cstdio>
#include <queue>

#define rep(i, n) for (int i = 0; i < (n); i++)

using namespace std;

const int INF = 1 << 29;

class edge {
public:
  int v, cost;
  edge(int v, int cost) : v(v), cost(cost) {}
};

int main() {
  for (int n, m, k; scanf("%d%d%d", &n, &m, &k), n;) {
    vector<edge> G[100];
    rep(_, m) {
      int u, v, cost;
      scanf("%d%d%d", &u, &v, &cost);
      G[u].push_back(edge(v, cost));
      G[v].push_back(edge(u, cost));
    }

    int d[100], dp[100];
    rep(u, n) {
      d[u] = (u == 0 ? 0 : INF);
      dp[u] = (u == 0 ? 1 : 0);
    }
    priority_queue<pair<int, int>> Q;
    Q.push(make_pair(0, 0));
    vector<int> D[100]; // 最短経路 DAG
    while (!Q.empty()) {
      int d_now = -Q.top().first, u = Q.top().second;
      Q.pop();
      if (d[u] < d_now)
        continue;

      rep(i, G[u].size()) {
        int v = G[u][i].v, cost = G[u][i].cost;
        if (d[v] > d[u] + cost) {
          d[v] = d[u] + cost;
          dp[v] = dp[u];
          Q.push(make_pair(-d[v], v));

          D[v].clear();
          D[v].push_back(
              u); // まずは辺の向きを逆にして保存しておいて、あとで直す
        } else if (d[v] == d[u] + cost) {
          dp[v] += dp[u];
          D[v].push_back(u);
        }
      }
    }
    int N = dp[n - 1]; // 0 - n-1 間の最短経路の個数

    vector<int> tmp[100];
    rep(u, n) tmp[u] = D[u], D[u].clear();
    rep(u, n) rep(i, tmp[u].size()) D[tmp[u][i]].push_back(u);

    rep(_, k) {
      int c;
      scanf("%d", &c);

      int dp2[100];
      rep(u, n) dp2[u] = 0;
      dp2[c] = 1;
      queue<int> Q;
      Q.push(c);
      while (!Q.empty()) {
        int u = Q.front();
        Q.pop();
        rep(i, D[u].size()) {
          int v = D[u][i];
          if (dp2[v] == 0)
            Q.push(v);
          dp2[v] += dp2[u];
        }
      }

      printf("%.9f\\n", (double)dp[c] * dp2[n - 1] / N);
    }
    puts("");
  }

  return 0;
}