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

#include <cstdio>
#include <cstring>
#include <queue>

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

using namespace std;

typedef long long ll;

const int INF = 1 << 29;

struct edge {
  int v, cost;
};

void Dijkstra(int n, const vector<edge> *G, int s, int *dist) {
  rep(u, n) dist[u] = (u == s ? 0 : INF);
  priority_queue<pair<int, int>> Q;
  Q.push(make_pair(0, s));
  while (!Q.empty()) {
    int d_now = -Q.top().first, u = Q.top().second;
    Q.pop();
    if (d_now > dist[u])
      continue;
    rep(i, G[u].size()) {
      int v = G[u][i].v, cost = G[u][i].cost;
      if (dist[v] > dist[u] + cost) {
        dist[v] = dist[u] + cost;
        Q.push(make_pair(-dist[v], v));
      }
    }
  }
}

int main() {
  int n, m;
  scanf("%d%d", &n, &m);
  static vector<edge> G[100000];
  rep(i, m) {
    int u, v, cost;
    scanf("%d%d%d", &u, &v, &cost);
    u--;
    v--;
    G[u].push_back((edge){v, cost});
    G[v].push_back((edge){u, cost});
  }

  int a, b, q;
  scanf("%d%d%d", &a, &b, &q);
  a--;
  b--;
  static int c[40000], d[40000];
  rep(i, q) scanf("%d%d", c + i, d + i), c[i]--, d[i]--;

  // calculate distances from a/b
  static int dist_a[100000];
  Dijkstra(n, G, a, dist_a);
  static int dist_b[100000];
  Dijkstra(n, G, b, dist_b);

  // build the shortest path DAG from a to b
  static vector<int> H[100000];
  rep(u, n) rep(i, G[u].size()) {
    int v = G[u][i].v, cost = G[u][i].cost;
    if (dist_a[u] + cost + dist_b[v] == dist_a[b])
      H[u].push_back(v);
  }

  // find a topological order of H
  vector<int> top;
  static int deg[100000]; // degree of vertices
  rep(u, n) rep(i, H[u].size()) {
    int v = H[u][i];
    deg[v]++;
  }
  queue<int> Q;
  Q.push(a);
  while (!Q.empty()) {
    int u = Q.front();
    Q.pop();
    top.push_back(u);
    rep(i, H[u].size()) {
      int v = H[u][i];
      deg[v]--;
      if (deg[v] == 0)
        Q.push(v);
    }
  }

  // query
  rep(i, (q + 63) / 64) {
    static ll dp[100000];
    memset(dp, 0, sizeof dp);
    rep(j, 64) if (64 * i + j < q) dp[c[64 * i + j]] |= 1LL << j;
    rep(i, top.size()) {
      int u = top[i];
      rep(j, H[u].size()) {
        int v = H[u][j];
        dp[v] |= dp[u];
      }
    }
    rep(j, 64) if (64 * i + j < q)
        puts(dp[d[64 * i + j]] & (1LL << j) ? "Yes" : "No");
  }

  return 0;
}

Error: TLE

Fixed submission:

#include <cstdio>
#include <cstring>
#include <queue>

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

using namespace std;

typedef long long ll;

const int INF = 1 << 29;

struct edge {
  int v, cost;
};

void Dijkstra(int n, const vector<edge> *G, int s, int *dist) {
  rep(u, n) dist[u] = (u == s ? 0 : INF);
  priority_queue<pair<int, int>> Q;
  Q.push(make_pair(0, s));
  while (!Q.empty()) {
    int d_now = -Q.top().first, u = Q.top().second;
    Q.pop();
    if (d_now > dist[u])
      continue;
    rep(i, G[u].size()) {
      int v = G[u][i].v, cost = G[u][i].cost;
      if (dist[v] > dist[u] + cost) {
        dist[v] = dist[u] + cost;
        Q.push(make_pair(-dist[v], v));
      }
    }
  }
}

int main() {
  int n, m;
  scanf("%d%d", &n, &m);
  static vector<edge> G[100000];
  rep(i, m) {
    int u, v, cost;
    scanf("%d%d%d", &u, &v, &cost);
    u--;
    v--;
    G[u].push_back((edge){v, cost});
    G[v].push_back((edge){u, cost});
  }

  int a, b, q;
  scanf("%d%d%d", &a, &b, &q);
  a--;
  b--;
  static int c[40000], d[40000];
  rep(i, q) scanf("%d%d", c + i, d + i), c[i]--, d[i]--;

  // calculate distances from a/b
  static int dist_a[100000];
  Dijkstra(n, G, a, dist_a);
  static int dist_b[100000];
  Dijkstra(n, G, b, dist_b);

  // build the shortest path DAG from a to b
  static vector<int> H[100000];
  rep(u, n) rep(i, G[u].size()) {
    int v = G[u][i].v, cost = G[u][i].cost;
    if (dist_a[u] + cost + dist_b[v] == dist_a[b])
      H[u].push_back(v);
  }

  // find a topological order of H
  vector<int> top;
  static int deg[100000]; // degree of vertices
  rep(u, n) rep(i, H[u].size()) {
    int v = H[u][i];
    deg[v]++;
  }
  queue<int> Q;
  Q.push(a);
  while (!Q.empty()) {
    int u = Q.front();
    Q.pop();
    top.push_back(u);
    rep(i, H[u].size()) {
      int v = H[u][i];
      deg[v]--;
      if (deg[v] == 0)
        Q.push(v);
    }
  }
  // printf("n=%d, a=%d, b=%d: ",n,a,b);
  // rep(i,top.size()) printf("%d ",top[i]); puts("");

  // query
  /*
          rep(i,(q+63)/64){
                  static ll dp[100000];
                  memset(dp,0,sizeof dp);
                  rep(j,64) if(64*i+j<q) dp[c[64*i+j]]|=1LL<<j;
                  rep(i,n){
                          int u=top[i];
                          rep(j,H[u].size()){
                                  int v=H[u][j];
                                  dp[v]|=dp[u];
                          }
                  }
                  rep(j,64) if(64*i+j<q)
     puts(dp[d[64*i+j]]&(1LL<<j)?"Yes":"No");
          }
  */
  // naive
  rep(i, q) {
    static bool vis[100000];
    rep(u, n) vis[u] = false;
    vis[c[i]] = true;
    rep(j, top.size()) {
      int u = top[j];
      rep(k, H[u].size()) {
        int v = H[u][k];
        vis[v] |= vis[u];
      }
    }
    /*
                    Q.push(c[i]);
                    while(!Q.empty()){
                            int u=Q.front(); Q.pop();
                            vis[u]=true;
                            rep(j,H[u].size()){
                                    int v=H[u][j];
                                    if(!vis[v]) vis[v]=true, Q.push(v);
                            }
                    }
    */
    puts(vis[d[i]] ? "Yes" : "No");
  }

  return 0;
}