Problem p03682 (C++)

Buggy submission (status: Time Limit Exceeded):
#include <algorithm>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <iterator>
#include <map>
#include <unordered_map>
#include <vector>
using namespace std;

// 優先度付きキュー
class class_PrQue {
public:
  class_PrQue(){};
  virtual ~class_PrQue(){};
  bool Push(int to, int from, int64_t Cost);
  bool Pop(int &rtn_to, int &rtn_from, int64_t &rtn_Cost);

protected:
  multimap<int64_t, pair<int, int>> Que_Cost; // cost < to , from >
  unordered_map<int, int64_t> Que_Num;        // 		<to, 	Cost	>
};

bool class_PrQue::Push(int to, int from, int64_t Cost) {
  auto qNum = Que_Num.find(to);
  if (qNum != Que_Num.end()) {
    // 同一Key は存在する。

    if (qNum->second < Cost) {
      return false;
    } // 登録済みの方が 低コストのため 無変更

    // 一旦削除

    // Que_Cost 側から削除
    auto p = Que_Cost.equal_range(qNum->second);
    for (auto it = p.first; it != p.second; ++it) {
      if (it->second.first == qNum->first) {
        Que_Cost.erase(it);
        break;
      }
    }

    // Que_Num 側から削除
    Que_Num.erase(qNum);
  }

  // 登録
  Que_Cost.emplace(Cost, make_pair(to, from));
  Que_Num.emplace(to, Cost);
  return true;
}

bool class_PrQue::Pop(int &rtn_to, int &rtn_from, int64_t &rtn_Cost) {
  auto topMean = Que_Cost.begin();
  if (topMean == Que_Cost.end()) {
    // Que 内に存在しない。
    return false;
  }
  rtn_Cost = topMean->first;
  rtn_to = topMean->second.first;
  rtn_from = topMean->second.second;

  // Queから削除
  Que_Num.erase(Que_Num.find(rtn_to));
  Que_Cost.erase(Que_Cost.begin());
  return true;
}

// 最小被覆木（最小全域木）

struct Edge {
  int to;
  int64_t cost;
};

class class_Prims {
public:
  class_Prims(){};
  virtual ~class_Prims(){};
  void init(int pointNum);
  void Set_1Way(int from, int to, int64_t cost) {
    inGraph[from].insert(make_pair(to, cost));
  }
  void Set_2Way(int p1, int p2, int64_t cost) {
    Set_1Way(p1, p2, cost);
    Set_1Way(p2, p1, cost);
  }
  void Search(int startPoint);
  int64_t Get_SumLength() { return SumLengh; }

  vector<vector<Edge>> AnsTree;
  vector<int64_t> Depth;
  void Print_AnsTree();

protected:
  int PointNum = 0;
  vector<map<int, int64_t>>
      inGraph; // map ならば Key(この場合 目的地) が同じものは登録されない
  int64_t SumLengh = 0;
};

void class_Prims::init(int pointNum) {
  PointNum = pointNum;
  inGraph.resize(pointNum);
  AnsTree.resize(pointNum);
  Depth.resize(pointNum);
}

void class_Prims::Print_AnsTree() {
  for (int i = 0; i < PointNum; i++) {
    printf("[%2d]: ", i);
    for (auto e : AnsTree[i]) {
      printf(" ->[%d:(%ld)] ", e.to, e.cost);
    }
    printf("\n");
  }
}

void class_Prims::Search(int startPoint) {
  vector<int> Color(PointNum);
  class_PrQue Que;
  SumLengh = 0;
  // 初期値格納
  for (auto next : inGraph[startPoint]) {
    Que.Push(next.first, startPoint, next.second);
    Color[next.first] = 1;
  }
  Color[startPoint] = 2;

  while (1) {
    int to;
    int from;
    int64_t cost;

    if (!Que.Pop(to, from, cost)) {
      break;
    } // キューが空=探索し終えた

    AnsTree[from].push_back({to, cost}); // 結果 木構造に登録
    SumLengh += cost;
    Depth[to] = Depth[from] + cost;
    Color[to] = 2;

    for (auto next : inGraph[to]) {
      if (Color[next.first] == 2) {
        continue;
      }
      Que.Push(next.first, to, next.second);
      Color[next.first] = 1;
    }
  }
}

struct struct_town {
  int n;
  int x;
  int y;
};

int main(int argc, char **argv) {
  (void)argc;
  (void)argv;

  class_Prims prims;
  int N;
  cin >> N;
  vector<struct_town> town(N + 1);
  for (int i = 1; i <= N; i++) {
    town[i].n = i;
    cin >> town[i].x >> town[i].y;
  }

  prims.init(N + 1);
  // printf("--\n");

  // x 方向
  stable_sort(
      town.begin(), town.end(),
      [](struct_town const &L, struct_town const &R) { return L.x < R.x; });

  for (int i = 2; i <= N; i++) {
    int c = min(abs(town[i].x - town[i - 1].x), abs(town[i].y - town[i - 1].y));
    prims.Set_2Way(town[i].n, town[i - 1].n, c);
    // printf("town[%d](%d,%d) : town[%d](%d,%d) : cost
    // :%d\n",i,town[i].x,town[i].y, i-1,town[i-1].x,town[i-1].y , c );
  }

  // printf("--\n");
  //  y 方向
  stable_sort(
      town.begin(), town.end(),
      [](struct_town const &L, struct_town const &R) { return L.y < R.y; });

  for (int i = 2; i <= N; i++) {
    int c = min(abs(town[i].x - town[i - 1].x), abs(town[i].y - town[i - 1].y));
    prims.Set_2Way(town[i].n, town[i - 1].n, c);
    // printf("town[%d](%d,%d) : town[%d](%d,%d) : cost
    // :%d\n",i,town[i].x,town[i].y, i-1,town[i-1].x,town[i-1].y , c );
  }

  prims.Search(1);
  // prims.Print_AnsTree();
  // printf("--\n");
  printf("%ld\n", prims.Get_SumLength());

  return 0;
}


Fixed submission:
#include <algorithm>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <iterator>
#include <map>
#include <unordered_map>
#include <vector>
using namespace std;

// 優先度付きキュー
class class_PrQue {
public:
  class_PrQue(){};
  virtual ~class_PrQue(){};
  bool Push(int to, int from, int64_t Cost);
  bool Pop(int &rtn_to, int &rtn_from, int64_t &rtn_Cost);

protected:
  multimap<int64_t, pair<int, int>> Que_Cost; // cost < to , from >
  unordered_map<int, int64_t> Que_Num;        // 		<to, 	Cost	>
};

bool class_PrQue::Push(int to, int from, int64_t Cost) {
  auto qNum = Que_Num.find(to);
  if (qNum != Que_Num.end()) {
    // 同一Key は存在する。

    if (qNum->second <= Cost) {
      return false;
    } // 登録済みの方が 低コストのため 無変更

    // 一旦削除

    // Que_Cost 側から削除
    auto p = Que_Cost.equal_range(qNum->second);
    for (auto it = p.first; it != p.second; ++it) {
      if (it->second.first == qNum->first) {
        Que_Cost.erase(it);
        break;
      }
    }

    // Que_Num 側から削除
    Que_Num.erase(qNum);
  }

  // 登録
  Que_Cost.emplace(Cost, make_pair(to, from));
  Que_Num.emplace(to, Cost);
  return true;
}

bool class_PrQue::Pop(int &rtn_to, int &rtn_from, int64_t &rtn_Cost) {
  auto topMean = Que_Cost.begin();
  if (topMean == Que_Cost.end()) {
    // Que 内に存在しない。
    return false;
  }
  rtn_Cost = topMean->first;
  rtn_to = topMean->second.first;
  rtn_from = topMean->second.second;

  // Queから削除
  Que_Num.erase(Que_Num.find(rtn_to));
  Que_Cost.erase(Que_Cost.begin());
  return true;
}

// 最小被覆木（最小全域木）

struct Edge {
  int to;
  int64_t cost;
};

class class_Prims {
public:
  class_Prims(){};
  virtual ~class_Prims(){};
  void init(int pointNum);
  void Set_1Way(int from, int to, int64_t cost) {
    inGraph[from].insert(make_pair(to, cost));
  }
  void Set_2Way(int p1, int p2, int64_t cost) {
    Set_1Way(p1, p2, cost);
    Set_1Way(p2, p1, cost);
  }
  void Search(int startPoint);
  int64_t Get_SumLength() { return SumLengh; }

  vector<vector<Edge>> AnsTree;
  vector<int64_t> Depth;
  void Print_AnsTree();

protected:
  int PointNum = 0;
  vector<map<int, int64_t>>
      inGraph; // map ならば Key(この場合 目的地) が同じものは登録されない
  int64_t SumLengh = 0;
};

void class_Prims::init(int pointNum) {
  PointNum = pointNum;
  inGraph.resize(pointNum);
  AnsTree.resize(pointNum);
  Depth.resize(pointNum);
}

void class_Prims::Print_AnsTree() {
  for (int i = 0; i < PointNum; i++) {
    printf("[%2d]: ", i);
    for (auto e : AnsTree[i]) {
      printf(" ->[%d:(%ld)] ", e.to, e.cost);
    }
    printf("\n");
  }
}

void class_Prims::Search(int startPoint) {
  vector<int> Color(PointNum);
  class_PrQue Que;
  SumLengh = 0;
  // 初期値格納
  for (auto next : inGraph[startPoint]) {
    Que.Push(next.first, startPoint, next.second);
    Color[next.first] = 1;
  }
  Color[startPoint] = 2;

  while (1) {
    int to;
    int from;
    int64_t cost;

    if (!Que.Pop(to, from, cost)) {
      break;
    } // キューが空=探索し終えた

    AnsTree[from].push_back({to, cost}); // 結果 木構造に登録
    SumLengh += cost;
    Depth[to] = Depth[from] + cost;
    Color[to] = 2;

    for (auto next : inGraph[to]) {
      if (Color[next.first] == 2) {
        continue;
      }
      Que.Push(next.first, to, next.second);
      Color[next.first] = 1;
    }
  }
}

struct struct_town {
  int n;
  int x;
  int y;
};

int main(int argc, char **argv) {
  (void)argc;
  (void)argv;

  class_Prims prims;
  int N;
  cin >> N;
  vector<struct_town> town(N + 1);
  for (int i = 1; i <= N; i++) {
    town[i].n = i;
    cin >> town[i].x >> town[i].y;
  }

  prims.init(N + 1);
  // printf("--\n");

  // x 方向
  stable_sort(
      town.begin(), town.end(),
      [](struct_town const &L, struct_town const &R) { return L.x < R.x; });

  for (int i = 2; i <= N; i++) {
    int c = min(abs(town[i].x - town[i - 1].x), abs(town[i].y - town[i - 1].y));
    prims.Set_2Way(town[i].n, town[i - 1].n, c);
    // printf("town[%d](%d,%d) : town[%d](%d,%d) : cost
    // :%d\n",i,town[i].x,town[i].y, i-1,town[i-1].x,town[i-1].y , c );
  }

  // printf("--\n");
  //  y 方向
  stable_sort(
      town.begin(), town.end(),
      [](struct_town const &L, struct_town const &R) { return L.y < R.y; });

  for (int i = 2; i <= N; i++) {
    int c = min(abs(town[i].x - town[i - 1].x), abs(town[i].y - town[i - 1].y));
    prims.Set_2Way(town[i].n, town[i - 1].n, c);
    // printf("town[%d](%d,%d) : town[%d](%d,%d) : cost
    // :%d\n",i,town[i].x,town[i].y, i-1,town[i-1].x,town[i-1].y , c );
  }

  prims.Search(1);
  // prims.Print_AnsTree();
  // printf("--\n");
  printf("%ld\n", prims.Get_SumLength());

  return 0;
}