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

#include <algorithm>
#include <bitset>
#include <cfloat>
#include <climits>
#include <cmath>
#include <iomanip>
#include <iostream>
#include <list>
#include <map>
#include <numeric>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <vector>
using namespace std;

class Edge {
public:
  int to, cost;
  Edge(){};
  Edge(int to0, int cost0) {
    to = to0;
    cost = cost0;
  }
};

void shortestPath(const vector<vector<Edge>> &edges, int start,
                  vector<int> &dist) {
  dist.assign(edges.size(), INT_MAX);
  dist[start] = 0;
  priority_queue<pair<int, int>, vector<pair<int, int>>,
                 greater<pair<int, int>>>
      q;
  q.push(make_pair(0, start));

  while (!q.empty()) {
    pair<int, int> p = q.top();
    q.pop();
    int v = p.second;
    if (dist[v] < p.first)
      continue;
    for (unsigned i = 0; i < edges[v].size(); ++i) {
      Edge e = edges[v][i];
      if (dist[v] + e.cost < dist[e.to]) {
        dist[e.to] = dist[v] + e.cost;
        q.push(make_pair(dist[e.to], e.to));
      }
    }
  }

  replace(dist.begin(), dist.end(), INT_MAX, -1);
}

void shortestPath(const vector<vector<Edge>> &edges,
                  vector<vector<int>> &dist) {
  dist.resize(edges.size());
  for (unsigned i = 0; i < edges.size(); ++i)
    shortestPath(edges, i, dist[i]);
}

int main() {
  for (;;) {
    int n;
    cin >> n;
    if (n == 0)
      return 0;

    map<string, int> index;
    vector<vector<Edge>> edges;
    vector<vector<int>> rev;
    for (int i = 0; i < n; ++i) {
      string s;
      cin >> s;
      string s1, s2;
      s1 = s.substr(0, s.find('-'));
      s2 = s.substr(s.find('-') + 1);

      int a, b;
      map<string, int>::iterator it;
      it = index.find(s1);
      if (it == index.end()) {
        a = edges.size();
        edges.resize(a + 1);
        rev.resize(a + 1);
        index[s1] = a;
      } else {
        a = it->second;
      }
      it = index.find(s2);
      if (it == index.end()) {
        b = edges.size();
        edges.resize(b + 1);
        rev.resize(b + 1);
        index[s2] = b;
      } else {
        b = it->second;
      }
      edges[a].push_back(Edge(b, 1));
      rev[b].push_back(a);
    }

    n = edges.size();
    vector<vector<bool>> check(n, vector<bool>(n, false));
    for (int i = 0; i < n; ++i) {
      for (unsigned j = 0; j < edges[i].size(); ++j) {
        int a = edges[i][j].to;
        for (unsigned k = 0; k < edges[a].size(); ++k) {
          int b = edges[a][k].to;
          check[i][b] = check[b][i] = true;
        }
      }
    }
    for (int i = 0; i < n; ++i) {
      for (unsigned j = 0; j < edges[i].size(); ++j) {
        for (unsigned k = j + 1; k < edges[i].size(); ++k) {
          if (edges[i][j].cost == 0 || edges[i][k].cost == 0)
            continue;
          int a = edges[i][j].to;
          int b = edges[i][k].to;
          if (!check[a][b]) {
            edges[a].push_back(Edge(b, 0));
            edges[b].push_back(Edge(a, 0));
            check[a][b] = check[b][a] = true;
          }
        }
      }
      for (unsigned j = 0; j < rev[i].size(); ++j) {
        for (unsigned k = j + 1; k < rev[i].size(); ++k) {
          int a = rev[i][j];
          int b = rev[i][k];
          if (!check[a][b]) {
            edges[a].push_back(Edge(b, 0));
            edges[b].push_back(Edge(a, 0));
            check[a][b] = check[b][a] = true;
          }
        }
      }
    }

    vector<vector<int>> dist;
    shortestPath(edges, dist);

    cout << n << endl;
    int m;
    cin >> m;
    for (int i = 0; i < m; ++i) {
      string s;
      cin >> s;
      string s1, s2;
      s1 = s.substr(0, s.find('-'));
      s2 = s.substr(s.find('-') + 1);

      int a, b;
      map<string, int>::iterator it;
      it = index.find(s1);
      if (it == index.end()) {
        cout << "NO" << endl;
        continue;
      }
      a = it->second;
      it = index.find(s2);
      if (it == index.end()) {
        cout << "NO" << endl;
        continue;
      }
      b = it->second;

      if (dist[a][b] != -1 && dist[a][b] % 2 == 1)
        cout << "YES" << endl;
      else
        cout << "NO" << endl;
    }
  }
}

Error: MLE

Fixed submission:

#include <algorithm>
#include <bitset>
#include <cfloat>
#include <climits>
#include <cmath>
#include <iomanip>
#include <iostream>
#include <list>
#include <map>
#include <numeric>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <vector>
using namespace std;

class Edge {
public:
  int to, cost;
  Edge(){};
  Edge(int to0, int cost0) {
    to = to0;
    cost = cost0;
  }
};

void shortestPath(const vector<vector<Edge>> &edges, int start,
                  vector<int> &dist) {
  dist.assign(edges.size(), INT_MAX);
  dist[start] = 0;
  priority_queue<pair<int, int>, vector<pair<int, int>>,
                 greater<pair<int, int>>>
      q;
  q.push(make_pair(0, start));

  while (!q.empty()) {
    pair<int, int> p = q.top();
    q.pop();
    int v = p.second;
    if (dist[v] < p.first)
      continue;
    for (unsigned i = 0; i < edges[v].size(); ++i) {
      Edge e = edges[v][i];
      if (dist[v] + e.cost < dist[e.to]) {
        dist[e.to] = dist[v] + e.cost;
        q.push(make_pair(dist[e.to], e.to));
      }
    }
  }

  replace(dist.begin(), dist.end(), INT_MAX, -1);
}

void shortestPath(const vector<vector<Edge>> &edges,
                  vector<vector<int>> &dist) {
  dist.resize(edges.size());
  for (unsigned i = 0; i < edges.size(); ++i)
    shortestPath(edges, i, dist[i]);
}

int main() {
  for (;;) {
    int n;
    cin >> n;
    if (n == 0)
      return 0;

    map<string, int> index;
    vector<vector<Edge>> edges;
    vector<vector<int>> rev;
    for (int i = 0; i < n; ++i) {
      string s;
      cin >> s;
      string s1, s2;
      s1 = s.substr(0, s.find('-'));
      s2 = s.substr(s.find('-') + 1);

      int a, b;
      map<string, int>::iterator it;
      it = index.find(s1);
      if (it == index.end()) {
        a = edges.size();
        edges.resize(a + 1);
        rev.resize(a + 1);
        index[s1] = a;
      } else {
        a = it->second;
      }
      it = index.find(s2);
      if (it == index.end()) {
        b = edges.size();
        edges.resize(b + 1);
        rev.resize(b + 1);
        index[s2] = b;
      } else {
        b = it->second;
      }
      edges[a].push_back(Edge(b, 1));
      rev[b].push_back(a);
    }

    n = edges.size();
    vector<vector<bool>> check(n, vector<bool>(n, false));
    for (int i = 0; i < n; ++i) {
      for (unsigned j = 0; j < edges[i].size(); ++j) {
        int a = edges[i][j].to;
        for (unsigned k = 0; k < rev[a].size(); ++k) {
          int b = rev[a][k];
          check[a][b] = check[b][a] = true;
        }
      }
    }
    for (int i = 0; i < n; ++i) {
      for (unsigned j = 1; j < edges[i].size(); ++j) {
        int a = edges[i][j - 1].to;
        int b = edges[i][j].to;
        if (!check[a][b]) {
          edges[a].push_back(Edge(b, 2));
          edges[b].push_back(Edge(a, 2));
        }
      }
      for (unsigned j = 1; j < rev[i].size(); ++j) {
        int a = rev[i][j - 1];
        int b = rev[i][j];
        if (!check[a][b]) {
          edges[a].push_back(Edge(b, 2));
          edges[b].push_back(Edge(a, 2));
        }
      }
    }

    vector<vector<int>> dist;
    shortestPath(edges, dist);

    cout << n << endl;
    int m;
    cin >> m;
    for (int i = 0; i < m; ++i) {
      string s;
      cin >> s;
      string s1, s2;
      s1 = s.substr(0, s.find('-'));
      s2 = s.substr(s.find('-') + 1);

      int a, b;
      map<string, int>::iterator it;
      it = index.find(s1);
      if (it == index.end()) {
        cout << "NO" << endl;
        continue;
      }
      a = it->second;
      it = index.find(s2);
      if (it == index.end()) {
        cout << "NO" << endl;
        continue;
      }
      b = it->second;

      if (dist[a][b] != -1 && dist[a][b] % 2 == 1)
        cout << "YES" << endl;
      else
        cout << "NO" << endl;
    }
  }
}