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

#include <algorithm>
#include <climits>
#include <iostream>
#include <list>
#include <stdio.h>
#include <vector>
using namespace std;

struct HeapNode {
  HeapNode() : v(0), key(INT_MAX){};
  HeapNode(int v, int key) : v(v), key(key){};
  int v;
  int key;
};

class MinHeap {
private:
  vector<HeapNode> vHeap;
  vector<int> vPos;

public:
  MinHeap(int V) : vHeap(V + 1), vPos(V) {
    for (int i = 1; i <= V; i++) {
      vHeap[i].v = i - 1;
      vPos[i - 1] = i;
    }
  }

  void percolateDown(int idx) {
    int smallest = idx;
    int leftChild = 2 * idx;
    int rightChild = 2 * idx + 1;

    if (leftChild < vHeap.size() &&
        vHeap[leftChild].key < vHeap[smallest].key) {
      smallest = leftChild;
    }

    if (rightChild < vHeap.size() &&
        vHeap[rightChild].key < vHeap[smallest].key) {
      smallest = rightChild;
    }
    // cout << "percolateDown " << idx << " " << smallest <<endl;
    if (smallest != idx) {
      HeapNode tmpNode = vHeap[idx];

      vPos[vHeap[idx].v] = smallest;
      vPos[vHeap[smallest].v] = idx;

      vHeap[idx] = vHeap[smallest];
      vHeap[smallest] = tmpNode;

      percolateDown(smallest);
    }
  }

  HeapNode extractMin() {
    HeapNode result = vHeap[1];
    // cout << "result " << result.v << " " << result.key << endl;

    int last = vHeap.size() - 1;
    vPos[result.v] = last;
    vPos[vHeap[last].v] = 1;
    vHeap[1] = vHeap[last];

    vHeap.pop_back();
    // printf("extractMin %d\\n", result.v);
    percolateDown(1);
    return result;
  }

  void decreaseKey(int v, int key) {
    int i = vPos[v];

    // printf("decreaseKey %d pos %d\\n", v, i);

    vHeap[i].key = key;

    while (i > 1 && vHeap[i].key < vHeap[i / 2].key) {
      // printf("decreaseKey exchange %d key %d %d key %d \\n", i, vHeap[i].key,
      // i/2, vHeap[i/2].key);
      HeapNode tmpNode = vHeap[i];

      vPos[vHeap[i].v] = i / 2;
      vPos[vHeap[i / 2].v] = i;

      vHeap[i] = vHeap[i / 2];
      vHeap[i / 2] = tmpNode;
      i = i / 2;
    }
  }

  bool isInHeap(int v) { return vPos[v] < vHeap.size(); }

  int getWeight(int v) {
    // cout << "getWeight " << v << " pos "<< vPos[v] << " key " <<
    // vHeap[vPos[v]].key << endl;
    return vHeap[vPos[v]].key;
  }
};

class Graph {
private:
  struct AdjNode {
    AdjNode(int dst, int weight) : dst(dst), weight(weight){};
    AdjNode() : dst(), weight(){};
    int dst;
    int weight;
  };
  vector<list<AdjNode>> vAdj;

public:
  Graph(int V) : vAdj(V) {}

  void addEdge(int src, int dst, int weight) {
    AdjNode adjNode(dst, weight);
    vAdj[src].push_back(adjNode);
    vAdj[dst].push_back(AdjNode(src, weight));
  };

  int prim() {
    int result = 0;
    int V = vAdj.size();
    vector<AdjNode> parent(vAdj.size());
    MinHeap vertexHeap(vAdj.size());

    vertexHeap.decreaseKey(0, 0);
    parent[0].dst = -1;
    parent[0].weight = 0;

    for (int i = 0; i < V - 1; i++) {
      HeapNode node = vertexHeap.extractMin();
      int v = node.v;
      list<AdjNode>::iterator it = vAdj[v].begin();
      for (it = vAdj[v].begin(); it != vAdj[v].end(); it++) {
        int u = it->dst;
        int weight = it->weight;
        if (vertexHeap.isInHeap(u) && weight < vertexHeap.getWeight(u)) {
          // printf("decreaseKey %d %d\\n", u, weight);
          vertexHeap.decreaseKey(u, weight);
          parent[u].dst = v;
          parent[u].weight = weight;
        }
      }
    }

    for (int i = 1; i < vAdj.size(); i++) {
      // printf("%d - %d weight %d\\n", parent[i].dst, i, parent[i].weight);
      result += parent[i].weight;
    }

    return result;
  }
};

int main() {
  // Let us create the graph given in above fugure
  int V, E;
  cin >> V >> E;
  Graph g(V);

  for (int i = 0; i < E; i++) {
    int src, dst, weight;
    cin >> src >> dst >> weight;
    g.addEdge(src, dst, weight);
  }

  cout << g.prim() << endl;

  return 0;
}

Error: MLE

Fixed submission:

#include <algorithm>
#include <climits>
#include <iostream>
#include <vector>
using namespace std;

class Graph {
private:
  int V;
  vector<vector<int>> graph;

public:
  Graph(int V) : V(V), graph(V, vector<int>(V, -1)){};

  void addEdge(int src, int dst, int weight) {
    graph[src][dst] = weight;
    graph[dst][src] = weight;
  }

  int findMin(const vector<int> &distance, const vector<bool> &inSet) {
    int min = INT_MAX;
    int index;

    for (int i = 0; i < distance.size(); i++) {
      if (inSet[i])
        continue;
      if (distance[i] < min) {
        min = distance[i];
        index = i;
      }
    }
    return index;
  }

  int prim() {
    vector<int> distance(V, INT_MAX);
    vector<bool> inSet(V, false);
    vector<int> parent(V);
    int result = 0;

    distance[0] = 0;
    parent[0] = 0;

    for (int i = 0; i < V - 1; i++) {
      int index = findMin(distance, inSet);
      inSet[index] = true;

      for (int j = 0; j < V; j++) {
        if (graph[index][j] != -1 && inSet[j] == false &&
            graph[index][j] < distance[j]) {
          parent[j] = index;
          distance[j] = graph[index][j];
        }
      }
    }

    for (int i = 1; i < V; i++) {
      result += graph[i][parent[i]];
      // printf("%d - %d    %d \\n", parent[i], i, graph[i][parent[i]]);
    }

    return result;
  }
};

int main() {
  int V, E;
  cin >> V >> E;
  Graph g(V);

  for (int i = 0; i < E; i++) {
    int src, dst, weight;
    cin >> src >> dst >> weight;
    g.addEdge(src, dst, weight);
  }

  cout << g.prim() << endl;

  return 0;
}