Problem p04034 (C++)

Buggy submission (status: Time Limit Exceeded):
#include <algorithm>
#include <cassert>
#include <deque>
#include <fstream>
#include <iostream>
#include <map>
#include <math.h>
#include <memory>
#include <sstream>
#include <stdio.h>
#include <string>
#include <time.h>
#include <vector>

#define FOR(i, a, b) for (int i = (a); i < (b); ++i)
#define REP(i, n) FOR(i, 0, n)
#define POW(n) ((n) * (n))
#define ALL(a) (a).begin(), (a).end()
#define cerr                                                                   \
  if (false)                                                                   \
  cerr

using namespace std;

typedef long long ll;
typedef unsigned long long ull;

typedef vector<int> vi;
typedef vector<double> vd;
typedef vector<string> vs;
typedef vector<unsigned long long> vull;

int N, M;
vi list;

struct UnionFind {
  vi root;
  vi sizes;

  UnionFind(int max) : root(max), sizes(max, 1) {
    REP(i, max) { root[i] = i; }
  }

  int find(int x) {
    if (x == root[x])
      return x;

    return root[x] = find(root[x]);
  }

  void unite(int x, int y) {
    x = find(x);
    y = find(y);

    if (x == y)
      return;

    if (sizes[x] < sizes[y])
      swap(x, y);
    if (y == 0) {
      swap(x, y);
    }

    root[y] = x;
    sizes[x] += sizes[y];

    sizes[y] = -1;
  }

  bool same(int x, int y) { return find(x) == find(y); }

  int size(int x) { return sizes[find(x)]; }

  void remove(int x) {

    REP(i, root.size()) {
      if (i == 0)
        continue;
      if (root[i] == x)
        root[i] = 0;
    }
    root[x] = x;
    sizes[0]--;
  }
};

void solve() {}

int main() {
  cin >> N >> M;

  list.resize(N + 1, 1);

  UnionFind uf(N + 1);
  uf.unite(0, 1);

  REP(i, M) {
    int s1, s2;
    cin >> s1 >> s2;

    list[s1]--;
    list[s2]++;

    // 可能性あり
    if (uf.same(s1, 0)) {
      uf.unite(s1, s2);
      if (list[s1] == 0)
        uf.remove(s1);
    }
  }

  // cout << (uf.size(0)-1) << endl;
  ll ans = -1;
  for (int v : uf.root) {
    if (v == 0)
      ans++;
  }
  cout << ans << endl;

  return 0;
}


Fixed submission:
#include <algorithm>
#include <cassert>
#include <deque>
#include <fstream>
#include <iostream>
#include <map>
#include <math.h>
#include <memory>
#include <sstream>
#include <stdio.h>
#include <string>
#include <time.h>
#include <vector>

#define FOR(i, a, b) for (int i = (a); i < (b); ++i)
#define REP(i, n) FOR(i, 0, n)
#define POW(n) ((n) * (n))
#define ALL(a) (a).begin(), (a).end()
#define cerr                                                                   \
  if (false)                                                                   \
  cerr

using namespace std;

typedef long long ll;
typedef unsigned long long ull;

typedef vector<int> vi;
typedef vector<double> vd;
typedef vector<string> vs;
typedef vector<unsigned long long> vull;

int N, M;
vi list;

struct UnionFind {
  vi root;
  vi sizes;

  UnionFind(int max) : root(max), sizes(max, 1) {
    REP(i, max) { root[i] = i; }
  }

  int find(int x) {
    if (x == root[x])
      return x;

    return root[x] = find(root[x]);
  }

  void unite(int x, int y) {
    x = find(x);
    y = find(y);

    if (x == y)
      return;

    if (sizes[x] < sizes[y])
      swap(x, y);
    if (y == 0) {
      swap(x, y);
    }

    root[y] = x;
    sizes[x] += sizes[y];

    sizes[y] = -1;
  }

  bool same(int x, int y) { return find(x) == find(y); }

  int size(int x) { return sizes[find(x)]; }

  void remove(int x) {

    // REP(i,root.size()) {
    //	if (i == 0)continue;
    //	if (root[i] == x)root[i] = 0;
    // }
    root[x] = x;
    sizes[0]--;
  }
};

void solve() {}

int main() {
  cin >> N >> M;

  list.resize(N + 1, 1);

  UnionFind uf(N + 1);
  uf.unite(0, 1);

  REP(i, M) {
    int s1, s2;
    cin >> s1 >> s2;

    list[s1]--;
    list[s2]++;

    // 可能性あり
    if (uf.same(s1, 0)) {
      uf.unite(s1, s2);
      if (list[s1] == 0)
        uf.remove(s1);
    }
  }

  // cout << (uf.size(0)-1) << endl;
  ll ans = -1;
  for (int v : uf.root) {
    if (v == 0)
      ans++;
  }
  cout << ans << endl;

  return 0;
}