Problem p03045 (C++)

Buggy submission (status: Runtime Error):
#include "bits/stdc++.h"

using namespace std;
using ll = long long int;
using pii = pair<int, int>;
using pil = pair<int, ll>;

// Graph.h start--------------------------------------------
#pragma once

#include <vector>

using Weight = long long;

struct Vertex;
using Vertices = std::vector<Vertex *>;
struct Edge;
using Edges = std::vector<const Edge *>;

struct Vertex {
  const int id;
  Edges edges;
  Vertex(int id);
  void add_edge(const Edge *const p_e);
  void add_edge(const Edges &es);
};

struct Edge {
  Vertex *p_src, *p_dst;
  Weight weight;

  Edge(Vertex *p_src, Vertex *p_dst, Weight weight);
  Edge(const Edge &e);
  Edge &operator=(const Edge &de);
};

struct Graph {
  Vertices vertices;
  Edges edges;
  Graph(int nvertices);
  Graph();
  ~Graph();
  void add_edge(Edge *p_edge);
  void add_edge(int edge_src, int edge_dst, Weight w);
};

//----------------------------------------------------------

using namespace std;

Vertex::Vertex(int id) : id(id) {}
void Vertex::add_edge(const Edge *const p_e) { edges.push_back(p_e); }
void Vertex::add_edge(const Edges &es) {
  for (const auto &p_e : es) {
    add_edge(p_e);
  }
}

Edge::Edge(Vertex *p_src, Vertex *p_dst, Weight weight)
    : p_src(p_src), p_dst(p_dst), weight(weight) {}
Edge::Edge(const Edge &e) : Edge(e.p_src, e.p_dst, e.weight) {}
Edge &Edge::operator=(const Edge &e) {
  p_src = e.p_src;
  p_dst = e.p_dst;
  weight = e.weight;
  return *this;
}
bool operator<(const Edge &e1, const Edge &e2) {
  return e1.weight != e2.weight ? e1.weight > e2.weight : // !!INVERSE!!
             e1.p_src != e2.p_src ? e1.p_src->id < e2.p_src->id
                                  : e1.p_dst->id < e2.p_dst->id;
}

Graph::Graph(int nvertices) {
  for (int id = 0; id < nvertices; id++) {
    vertices.push_back(new Vertex(id));
  }
}
Graph::Graph() : Graph(0) {}
Graph::~Graph() {
  for (auto &p_vertex : vertices) {
    delete p_vertex;
  }
  for (auto &p_edge : edges) {
    delete p_edge;
  }
}
void Graph::add_edge(Edge *p_edge) {
  vertices[p_edge->p_src->id]->add_edge(p_edge);
  edges.push_back(p_edge);
}
void Graph::add_edge(int edge_src, int edge_dst, Weight w) {
  add_edge(new Edge(vertices[edge_src], vertices[edge_dst], w));
}

// Graph.h end----------------------------------------------
vector<bool> is_filled;

void fill(int s, int d, Graph &g) {
  is_filled[d] = true;
  for (const auto &p_e : g.vertices[d]->edges) {
    int nd = p_e->p_dst->id;
    if (is_filled[nd])
      continue;
    fill(d, nd, g);
  }
}

int main() {
  int N, M;
  cin >> N >> M;
  vector<int> x(N + 1), y(N + 1);
  for (int i = 0; i < M; i++) {
    int dummyz;
    cin >> x[i] >> y[i] >> dummyz;
  }
  Graph g(N + 1);
  for (int i = 0; i < M; i++) {
    g.add_edge(x[i], y[i], 0);
    g.add_edge(y[i], x[i], 0);
  }

  is_filled = vector<bool>(N + 1, false);
  int ans = 0;
  for (int i = 1; i <= N; i++) {
    if (is_filled[i])
      continue;
    fill(0, i, g);
    ans++;
  }

  cout << ans << endl;
  return 0;
}


Fixed submission:
#include "bits/stdc++.h"

using namespace std;
using ll = long long int;
using pii = pair<int, int>;
using pil = pair<int, ll>;

// Graph.h start--------------------------------------------
#pragma once

#include <vector>

using Weight = long long;

struct Vertex;
using Vertices = std::vector<Vertex *>;
struct Edge;
using Edges = std::vector<const Edge *>;

struct Vertex {
  const int id;
  Edges edges;
  Vertex(int id);
  void add_edge(const Edge *const p_e);
  void add_edge(const Edges &es);
};

struct Edge {
  Vertex *p_src, *p_dst;
  Weight weight;

  Edge(Vertex *p_src, Vertex *p_dst, Weight weight);
  Edge(const Edge &e);
  Edge &operator=(const Edge &de);
};

struct Graph {
  Vertices vertices;
  Edges edges;
  Graph(int nvertices);
  Graph();
  ~Graph();
  void add_edge(Edge *p_edge);
  void add_edge(int edge_src, int edge_dst, Weight w);
};

//----------------------------------------------------------

using namespace std;

Vertex::Vertex(int id) : id(id) {}
void Vertex::add_edge(const Edge *const p_e) { edges.push_back(p_e); }
void Vertex::add_edge(const Edges &es) {
  for (const auto &p_e : es) {
    add_edge(p_e);
  }
}

Edge::Edge(Vertex *p_src, Vertex *p_dst, Weight weight)
    : p_src(p_src), p_dst(p_dst), weight(weight) {}
Edge::Edge(const Edge &e) : Edge(e.p_src, e.p_dst, e.weight) {}
Edge &Edge::operator=(const Edge &e) {
  p_src = e.p_src;
  p_dst = e.p_dst;
  weight = e.weight;
  return *this;
}
bool operator<(const Edge &e1, const Edge &e2) {
  return e1.weight != e2.weight ? e1.weight > e2.weight : // !!INVERSE!!
             e1.p_src != e2.p_src ? e1.p_src->id < e2.p_src->id
                                  : e1.p_dst->id < e2.p_dst->id;
}

Graph::Graph(int nvertices) {
  for (int id = 0; id < nvertices; id++) {
    vertices.push_back(new Vertex(id));
  }
}
Graph::Graph() : Graph(0) {}
Graph::~Graph() {
  for (auto &p_vertex : vertices) {
    delete p_vertex;
  }
  for (auto &p_edge : edges) {
    delete p_edge;
  }
}
void Graph::add_edge(Edge *p_edge) {
  vertices[p_edge->p_src->id]->add_edge(p_edge);
  edges.push_back(p_edge);
}
void Graph::add_edge(int edge_src, int edge_dst, Weight w) {
  add_edge(new Edge(vertices[edge_src], vertices[edge_dst], w));
}

// Graph.h end----------------------------------------------
vector<bool> is_filled;

void fill(int s, int d, Graph &g) {
  is_filled[d] = true;
  for (const auto &p_e : g.vertices[d]->edges) {
    int nd = p_e->p_dst->id;
    if (is_filled[nd])
      continue;
    fill(d, nd, g);
  }
}

int main() {
  int N, M;
  cin >> N >> M;
  vector<int> x(M), y(M);
  for (int i = 0; i < M; i++) {
    int dummyz;
    cin >> x[i] >> y[i] >> dummyz;
  }
  Graph g(N + 1);
  for (int i = 0; i < M; i++) {
    g.add_edge(x[i], y[i], 0);
    g.add_edge(y[i], x[i], 0);
  }

  is_filled = vector<bool>(N + 1, false);
  int ans = 0;
  for (int i = 1; i <= N; i++) {
    if (is_filled[i])
      continue;
    fill(0, i, g);
    ans++;
  }

  cout << ans << endl;
  return 0;
}