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

#include <iostream>

#include <cstdio>
#include <cstdlib>

#include <stdint.h>

typedef uint8_t u8;
typedef uint16_t u16;
typedef uint32_t u32;
typedef uint64_t u64;
typedef int8_t s8;
typedef int16_t s16;
typedef int32_t s32;
typedef int64_t s64;

const int INF = (1 << 28);
const long INFL = (1LL << 50);

class FastIO {
public:
  void flush() {
    fflush(stdin);
    fflush(stdout);
  }
  FastIO &operator>>(int &right) {
    if (scanf("%d", &right) == EOF) {
      flush();
      exit(0);
    }
    return *this;
  }
  FastIO &operator>>(u64 &right) {
    if (scanf("%ld", &right) == EOF) {
      flush();
      exit(0);
    }
    return *this;
  }
  FastIO &operator>>(s64 &right) {
    if (scanf("%ld", &right) == EOF) {
      flush();
      exit(0);
    }
    return *this;
  }
  FastIO &operator>>(u32 &right) {
    if (scanf("%d", &right) == EOF) {
      flush();
      exit(0);
    }
    return *this;
  }
  FastIO &operator>>(double &right) {
    if (scanf("%lf", &right) == EOF) {
      flush();
      exit(0);
    }
    return *this;
  }
  FastIO &operator>>(char &right) {
    if (scanf("%c", &right) == EOF) {
      flush();
      exit(0);
    }
    return *this;
  }
  FastIO &operator>>(char right[]) {
    if (scanf("%s", right) == EOF) {
      flush();
      exit(0);
    }
    return *this;
  }
  FastIO &operator<<(const int &right) {
    printf("%d", right);
    return *this;
  }
  FastIO &operator<<(const u32 &right) {
    printf("%d", right);
    return *this;
  }
  FastIO &operator<<(const u64 &right) {
    printf("%ld", right);
    return *this;
  }
  FastIO &operator<<(const s64 &right) {
    printf("%ld", right);
    return *this;
  }
  FastIO &operator<<(const double &right) {
    printf("%.20lf", right);
    return *this;
  }

  FastIO &operator<<(const char right[]) {
    printf("%s", right);
    return *this;
  }

  FastIO &operator<<(const char &right) {
    printf("%c", right);
    return *this;
  }
};

FastIO io;

#include <cstdint>

typedef uint32_t u32;

class void_ {};

template <typename T> class Weight {
protected:
  T w_;

public:
  const T &weight() const;
};

template <> class Weight<void_> : public void_ {};

template <typename Tweight> const Tweight &Weight<Tweight>::weight() const {
  return w_;
}

template <typename Tweight> class Edge : public Weight<Tweight> {
public:
  Edge();
  Edge(u32 from, u32 to);
  Edge(u32 from, u32 to, Tweight w);
  const u32 &from() const;
  const u32 &to() const;
  Edge reverse();
  void dump();

private:
  u32 s, t;
};

template <typename Tweight> Edge<Tweight>::Edge() {}

template <typename Tweight> Edge<Tweight>::Edge(u32 from, u32 to) {
  s = from;
  t = to;
}

template <typename Tweight> Edge<Tweight>::Edge(u32 from, u32 to, Tweight w) {
  s = from;
  t = to;
  this->w_ = w;
}

template <typename Tweight> const u32 &Edge<Tweight>::from() const { return s; }

template <typename Tweight> const u32 &Edge<Tweight>::to() const { return t; }

template <typename Tweight> Edge<Tweight> Edge<Tweight>::reverse() {
  Edge res = *this;
  u32 tmp;
  tmp = s;
  s = t;
  t = tmp;
  return res;
}

template <typename Tweight, bool isdirected, u32 maxV, u32 maxE> class Graph {
public:
  Graph();
  Graph(u32 V);
  void insert(Edge<Tweight> edge);
  u32 Vsize();
  void activate();
  Edge<Tweight> *adjust(u32 v);
  u32 adjust_size(u32 v);

private:
  Edge<Tweight> edge_[maxE];
  u32 edge_num;
  u32 vertex_num;
  u32 adjust_size_[maxV];
  u32 index[maxV];
};

template <typename T, typename U> T Max(T arg1, U arg2) {
  T arg2T = static_cast<T>(arg2);
  if (arg1 < arg2T)
    return arg2T;
  return arg1;
}

template <typename T, typename U> T Min(T arg1, U arg2) {
  T arg2T = static_cast<T>(arg2);
  if (arg2T < arg1)
    return arg2T;
  return arg1;
}

template <typename Tweight, bool isdirected, u32 maxV, u32 maxE>
Graph<Tweight, isdirected, maxV, maxE>::Graph() {
  edge_num = 0;
  vertex_num = 0;
  for (int i = 0; i < maxV; ++i) {
    adjust_size_[i] = 0;
    index[i] = 0;
  }
}

template <typename Tweight, bool isdirected, u32 maxV, u32 maxE>
Graph<Tweight, isdirected, maxV, maxE>::Graph(u32 V) {
  edge_num = 0;
  vertex_num = V;
  for (int i = 0; i < maxV; ++i) {
    adjust_size_[i] = 0;
    index[i] = 0;
  }
}

template <typename Tweight, bool isdirected, u32 maxV, u32 maxE>
void Graph<Tweight, isdirected, maxV, maxE>::insert(Edge<Tweight> edge) {
  edge_[edge_num] = edge;
  edge_num += 1;
  if (not isdirected) {
    edge_[edge_num] = edge.reverse();
    edge_num += 1;
  }
  vertex_num = Max(vertex_num, edge.from());
  vertex_num = Max(vertex_num, edge.to());
}

template <typename Tweight, bool isdirected, u32 maxV, u32 maxE>
void Graph<Tweight, isdirected, maxV, maxE>::activate() {
  Edge<Tweight> buffer[maxE];
  u32 E = edge_num;
  u32 count[maxV];
  for (int i = 0; i < maxV; ++i)
    count[i] = 0;
  for (int i = 0; i < E; ++i) {
    count[edge_[i].from()] += 1;
  }
  for (int i = 0; i < maxV; ++i) {
    adjust_size_[i] = count[i];
  }
  int t = 0;
  for (int i = 0; i < maxV; ++i) {
    t += count[i];
    count[i] = t - count[i];
    index[i] = count[i];
  }
  for (int i = 0; i < E; ++i) {
    buffer[count[edge_[i].from()]] = edge_[i];
    count[edge_[i].from()] += 1;
  }
  for (int i = 0; i < E; ++i) {
    edge_[i] = buffer[i];
  }
}

template <typename Tweight, bool isdirected, u32 maxV, u32 maxE>
Edge<Tweight> *Graph<Tweight, isdirected, maxV, maxE>::adjust(u32 v) {
  return &edge_[index[v]];
}

template <typename Tweight, bool isdirected, u32 maxV, u32 maxE>
u32 Graph<Tweight, isdirected, maxV, maxE>::adjust_size(u32 v) {
  return adjust_size_[v];
}

template <typename Tweight, bool isdirected, u32 maxV, u32 maxE>
u32 Graph<Tweight, isdirected, maxV, maxE>::Vsize() {
  return vertex_num;
}

u64 rdtsc() {
  u64 u, l;
  __asm__ volatile("rdtsc" : "=a"(l), "=d"(u));
  return (u << 32) | l;
}

template <typename Tweight, u32 maxV, u32 maxE>
void topological_sort(Graph<Tweight, true, maxV, maxE> &graph, int *id) {
  bool used[maxV] = {};
  int k = graph.Vsize();
  for (int i = 1; i <= graph.Vsize(); ++i) {
    if (not used[i]) {
      topological_sort_dfs(graph, id, used, i, k);
    }
  }
}

template <typename Tweight, u32 maxV, u32 maxE>
void topological_sort_dfs(Graph<Tweight, true, maxV, maxE> &graph, int *id,
                          bool *used, int i, int &k) {
  if (used[i])
    return;
  used[i] = true;
  u32 n = graph.adjust_size(i);
  for (int j = 0; j < n; ++j) {
    topological_sort_dfs(graph, id, used, graph.adjust(i)[j].to(), k);
  }
  id[k] = i;
  k -= 1;
}

class Solver {
private:
public:
  void solve() {
    int V, E;
    std::cin >> V >> E;
    Edge<void_> edge;
    Graph<void_, true, 10010, 100100> graph(V);
    for (int i = 0; i < E; ++i) {
      int s, t;
      std::cin >> s >> t;
      graph.insert(Edge<void_>(s + 1, t + 1));
    }
    graph.activate();
    int id[10100] = {};
    topological_sort(graph, id);
    for (int i = 1; i <= V; ++i) {
      // if( not ( 1 <= id[i] and id[i] <= V ) ) exit(1);
      std::cout << id[i] - 1 << std::endl;
    }
  }
};

int main() {

  Solver solver;
  solver.solve();

  return 0;
}

Error: WA

Fixed submission:

#include <iostream>

#include <cstdio>
#include <cstdlib>

#include <stdint.h>

typedef uint8_t u8;
typedef uint16_t u16;
typedef uint32_t u32;
typedef uint64_t u64;
typedef int8_t s8;
typedef int16_t s16;
typedef int32_t s32;
typedef int64_t s64;

const int INF = (1 << 28);
const long INFL = (1LL << 50);

class FastIO {
public:
  void flush() {
    fflush(stdin);
    fflush(stdout);
  }
  FastIO &operator>>(int &right) {
    if (scanf("%d", &right) == EOF) {
      flush();
      exit(0);
    }
    return *this;
  }
  FastIO &operator>>(u64 &right) {
    if (scanf("%ld", &right) == EOF) {
      flush();
      exit(0);
    }
    return *this;
  }
  FastIO &operator>>(s64 &right) {
    if (scanf("%ld", &right) == EOF) {
      flush();
      exit(0);
    }
    return *this;
  }
  FastIO &operator>>(u32 &right) {
    if (scanf("%d", &right) == EOF) {
      flush();
      exit(0);
    }
    return *this;
  }
  FastIO &operator>>(double &right) {
    if (scanf("%lf", &right) == EOF) {
      flush();
      exit(0);
    }
    return *this;
  }
  FastIO &operator>>(char &right) {
    if (scanf("%c", &right) == EOF) {
      flush();
      exit(0);
    }
    return *this;
  }
  FastIO &operator>>(char right[]) {
    if (scanf("%s", right) == EOF) {
      flush();
      exit(0);
    }
    return *this;
  }
  FastIO &operator<<(const int &right) {
    printf("%d", right);
    return *this;
  }
  FastIO &operator<<(const u32 &right) {
    printf("%d", right);
    return *this;
  }
  FastIO &operator<<(const u64 &right) {
    printf("%ld", right);
    return *this;
  }
  FastIO &operator<<(const s64 &right) {
    printf("%ld", right);
    return *this;
  }
  FastIO &operator<<(const double &right) {
    printf("%.20lf", right);
    return *this;
  }

  FastIO &operator<<(const char right[]) {
    printf("%s", right);
    return *this;
  }

  FastIO &operator<<(const char &right) {
    printf("%c", right);
    return *this;
  }
};

FastIO io;

#include <cstdint>

typedef uint32_t u32;

class void_ {};

template <typename T> class Weight {
protected:
  T w_;

public:
  const T &weight() const;
};

template <> class Weight<void_> : public void_ {};

template <typename Tweight> const Tweight &Weight<Tweight>::weight() const {
  return w_;
}

template <typename Tweight> class Edge : public Weight<Tweight> {
public:
  Edge();
  Edge(u32 from, u32 to);
  Edge(u32 from, u32 to, Tweight w);
  const u32 &from() const;
  const u32 &to() const;
  Edge reverse();
  void dump();

private:
  u32 s, t;
};

template <typename Tweight> Edge<Tweight>::Edge() {}

template <typename Tweight> Edge<Tweight>::Edge(u32 from, u32 to) {
  s = from;
  t = to;
}

template <typename Tweight> Edge<Tweight>::Edge(u32 from, u32 to, Tweight w) {
  s = from;
  t = to;
  this->w_ = w;
}

template <typename Tweight> const u32 &Edge<Tweight>::from() const { return s; }

template <typename Tweight> const u32 &Edge<Tweight>::to() const { return t; }

template <typename Tweight> Edge<Tweight> Edge<Tweight>::reverse() {
  Edge res = *this;
  u32 tmp;
  tmp = s;
  s = t;
  t = tmp;
  return res;
}

template <typename Tweight, bool isdirected, u32 maxV, u32 maxE> class Graph {
public:
  Graph();
  void insert(Edge<Tweight> edge);
  u32 Vsize();
  void activate();
  Edge<Tweight> *adjust(u32 v);
  u32 adjust_size(u32 v);

private:
  Edge<Tweight> edge_[maxE];
  u32 edge_num;
  u32 vertex_num;
  u32 adjust_size_[maxV];
  u32 index[maxV];
};

template <typename T, typename U> T Max(T arg1, U arg2) {
  T arg2T = static_cast<T>(arg2);
  if (arg1 < arg2T)
    return arg2T;
  return arg1;
}

template <typename T, typename U> T Min(T arg1, U arg2) {
  T arg2T = static_cast<T>(arg2);
  if (arg2T < arg1)
    return arg2T;
  return arg1;
}

template <typename Tweight, bool isdirected, u32 maxV, u32 maxE>
Graph<Tweight, isdirected, maxV, maxE>::Graph() {
  edge_num = 0;
  vertex_num = 0;
  for (int i = 0; i < maxV; ++i) {
    adjust_size_[i] = 0;
    index[i] = 0;
  }
}

template <typename Tweight, bool isdirected, u32 maxV, u32 maxE>
void Graph<Tweight, isdirected, maxV, maxE>::insert(Edge<Tweight> edge) {
  edge_[edge_num] = edge;
  edge_num += 1;
  if (not isdirected) {
    edge_[edge_num] = edge.reverse();
    edge_num += 1;
  }
  vertex_num = Max(vertex_num, edge.from());
  vertex_num = Max(vertex_num, edge.to());
}

template <typename Tweight, bool isdirected, u32 maxV, u32 maxE>
void Graph<Tweight, isdirected, maxV, maxE>::activate() {
  Edge<Tweight> buffer[maxE];
  u32 E = edge_num;
  u32 count[maxV];
  for (int i = 0; i < maxV; ++i)
    count[i] = 0;
  for (int i = 0; i < E; ++i) {
    count[edge_[i].from()] += 1;
  }
  for (int i = 0; i < maxV; ++i) {
    adjust_size_[i] = count[i];
  }
  int t = 0;
  for (int i = 0; i < maxV; ++i) {
    t += count[i];
    count[i] = t - count[i];
    index[i] = count[i];
  }
  for (int i = 0; i < E; ++i) {
    buffer[count[edge_[i].from()]] = edge_[i];
    count[edge_[i].from()] += 1;
  }
  for (int i = 0; i < E; ++i) {
    edge_[i] = buffer[i];
  }
}

template <typename Tweight, bool isdirected, u32 maxV, u32 maxE>
Edge<Tweight> *Graph<Tweight, isdirected, maxV, maxE>::adjust(u32 v) {
  return &edge_[index[v]];
}

template <typename Tweight, bool isdirected, u32 maxV, u32 maxE>
u32 Graph<Tweight, isdirected, maxV, maxE>::adjust_size(u32 v) {
  return adjust_size_[v];
}

template <typename Tweight, bool isdirected, u32 maxV, u32 maxE>
u32 Graph<Tweight, isdirected, maxV, maxE>::Vsize() {
  return vertex_num;
}

u64 rdtsc() {
  u64 u, l;
  __asm__ volatile("rdtsc" : "=a"(l), "=d"(u));
  return (u << 32) | l;
}

template <typename Tweight, u32 maxV, u32 maxE>
void topological_sort(Graph<Tweight, true, maxV, maxE> &graph, int *id) {
  bool used[maxV] = {};
  int k = graph.Vsize();
  for (int i = 1; i <= graph.Vsize(); ++i) {
    if (not used[i]) {
      topological_sort_dfs(graph, id, used, i, k);
    }
  }
}

template <typename Tweight, u32 maxV, u32 maxE>
void topological_sort_dfs(Graph<Tweight, true, maxV, maxE> &graph, int *id,
                          bool *used, int i, int &k) {
  if (used[i])
    return;
  used[i] = true;
  u32 n = graph.adjust_size(i);
  for (int j = 0; j < n; ++j) {
    topological_sort_dfs(graph, id, used, graph.adjust(i)[j].to(), k);
  }
  id[k] = i;
  k -= 1;
}

class Solver {
private:
public:
  void solve() {
    int V, E;
    std::cin >> V >> E;
    Edge<void_> edge;
    Graph<void_, true, 10010, 100100> graph;
    for (int i = 0; i < E; ++i) {
      int s, t;
      std::cin >> s >> t;
      graph.insert(Edge<void_>(s + 1, t + 1));
    }
    graph.activate();
    int id[10100] = {};
    topological_sort(graph, id);
    for (int i = 1; i <= V; ++i) {
      if (not(1 <= id[i] and id[i] <= V))
        exit(1);
      std::cout << id[i] - 1 << std::endl;
    }
  }
};

int main() {

  Solver solver;
  solver.solve();

  return 0;
}