Problem p02365 (C++) — buggy submission, verdict: Runtime Error

#include <algorithm>
#include <array>
#include <cstdio>
#include <functional>
#include <iostream>
#include <list>
#include <numeric>
#include <queue>
#include <sstream>
#include <stack>
#include <string>
#include <utility>
#include <vector>
#define _USE_MATH_DEFINES

#include <map>
#include <math.h>

#define SENTINEL 1000000001

#define min(a, b) ((a) > (b) ? (b) : (a))
#define max(a, b) ((a) > (b) ? (a) : (b))

#define INF 200000000

using namespace std;

typedef long long ll;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
typedef pair<ll, int> pli;

struct OwnEdge {
  int s, t, c;
  OwnEdge(int s, int t, int c) : s(s), t(t), c(c) {}
  OwnEdge() : s(-1), t(-1), c(-1) {}
  bool operator<(const OwnEdge &e) const { return c < e.c; }
  bool operator>(const OwnEdge &e) const { return c > e.c; }
};

ll MCA(vector<OwnEdge> &edges, int V, int r) {
  vector<pii> mins(V, pii(INF, -1));
  for (auto &e : edges) {
    mins[e.t] = min(mins[e.t], pii(e.c, e.s));
  }
  mins[r] = pii(-1, -1);

  vector<int> group(V, 0);
  vector<bool> isCycle(V, false);
  int counter = 0;

  vector<bool> checked(V, false);
  for (int i = 0; i < V; i++) {
    if (checked[i]) {
      continue;
    }
    vector<int> chain;
    int cursor = i;
    while (cursor != -1 && !checked[cursor]) {
      checked[cursor] = true;
      chain.push_back(cursor);
      cursor = mins[cursor].second;
    }
    if (cursor != -1) {
      bool inCycle = false;
      for (auto &n : chain) {
        group[n] = counter;
        if (n == cursor) {
          inCycle = true;
          isCycle[counter] = true;
        }
        if (!inCycle)
          counter++;
      }
      if (inCycle)
        counter++;
    } else {
      for (auto &n : chain) {
        group[n] = counter;
        counter++;
      }
    }
  }

  if (counter == V) {
    ll sum = 1;
    for (int i = 0; i < V; i++) {
      sum += mins[i].first;
    }
    return sum;
  }

  ll res = 0;
  for (int i = 0; i < V; i++) {
    if (i != r && isCycle[group[i]]) {
      res += mins[i].first;
    }
  }

  vector<OwnEdge> newEdge;
  for (auto &e : edges) {
    int to = e.t;
    int gfrom = group[e.s];
    int gto = group[e.t];

    if (gfrom == gto) {
      continue;
    } else if (isCycle[gto]) {
      newEdge.push_back(OwnEdge(gfrom, gto, e.c - mins[to].first));
    } else {
      newEdge.push_back(OwnEdge(gfrom, gto, e.c));
    }
  }

  return res + MCA(newEdge, counter, group[r]);
}

int main() {
  cin.tie(0);
  ios::sync_with_stdio(false);

  vector<OwnEdge> edges;

  int V, E, r;
  scanf("%d %d %d", &V, &E, &r);

  for (int i = 0; i < E; i++) {
    int s, t, d;
    scanf("%d %d %d", &s, &t, &d);

    edges.push_back(OwnEdge(s, t, d));
  }

  printf("%d\\n", MCA(edges, V, r));

  return 0;
}


Error: 0

Fixed submission:

#include <algorithm>
#include <array>
#include <cstdio>
#include <functional>
#include <iostream>
#include <list>
#include <numeric>
#include <queue>
#include <sstream>
#include <stack>
#include <string>
#include <utility>
#include <vector>
#define _USE_MATH_DEFINES

#include <map>
#include <math.h>

#define SENTINEL 1000000001

#define min(a, b) ((a) > (b) ? (b) : (a))
#define max(a, b) ((a) > (b) ? (a) : (b))

#define INF 200000000

using namespace std;

typedef long long ll;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
typedef pair<ll, int> pli;

struct OwnEdge {
  int s, t, c;
  OwnEdge(int s, int t, int c) : s(s), t(t), c(c) {}
  OwnEdge() : s(-1), t(-1), c(-1) {}
  bool operator<(const OwnEdge &e) const { return c < e.c; }
  bool operator>(const OwnEdge &e) const { return c > e.c; }
};

ll MCA(vector<OwnEdge> &edges, int V, int r) {
  vector<pii> mins(V, pii(INF, -1));
  for (auto &e : edges) {
    mins[e.t] = min(mins[e.t], pii(e.c, e.s));
  }
  mins[r] = pii(-1, -1);

  vector<int> group(V, 0);
  vector<bool> isCycle(V, false);
  int counter = 0;

  vector<bool> checked(V, false);
  for (int i = 0; i < V; i++) {
    if (checked[i]) {
      continue;
    }
    vector<int> chain;
    int cursor = i;
    while (cursor != -1 && !checked[cursor]) {
      checked[cursor] = true;
      chain.push_back(cursor);
      cursor = mins[cursor].second;
    }
    if (cursor != -1) {
      bool inCycle = false;
      for (auto &n : chain) {
        group[n] = counter;
        if (n == cursor) {
          inCycle = true;
          isCycle[counter] = true;
        }
        if (!inCycle)
          counter++;
      }
      if (inCycle)
        counter++;
    } else {
      for (auto &n : chain) {
        group[n] = counter;
        counter++;
      }
    }
  }

  if (counter == V) {
    ll sum = 1;
    for (auto &m : mins) {
      sum += m.first;
    }
    return sum;
  }

  ll res = 0;
  for (int i = 0; i < V; i++) {
    if (i != r && isCycle[group[i]]) {
      res += mins[i].first;
    }
  }

  vector<OwnEdge> newEdge;
  for (auto &e : edges) {
    int to = e.t;
    int gfrom = group[e.s];
    int gto = group[e.t];

    if (gfrom == gto) {
      continue;
    } else if (isCycle[gto]) {
      newEdge.push_back(OwnEdge(gfrom, gto, e.c - mins[to].first));
    } else {
      newEdge.push_back(OwnEdge(e.s, e.t, e.c));
    }
  }

  return res + MCA(newEdge, counter, group[r]);
}

int main() {
  cin.tie(0);
  ios::sync_with_stdio(false);

  vector<OwnEdge> edges;

  int V, E, r;
  scanf("%d %d %d", &V, &E, &r);

  for (int i = 0; i < E; i++) {
    int s, t, d;
    scanf("%d %d %d", &s, &t, &d);

    edges.push_back(OwnEdge(s, t, d));
  }

  printf("%d\\n", MCA(edges, V, r));

  return 0;
}