Problem p03441 (C++)

Buggy submission (status: Runtime Error):
#include <algorithm>
#include <cstdlib>
#include <functional>
#include <iostream>
#include <limits.h>
#include <map>
#include <math.h>
#include <numeric>
#include <queue>
#include <set>
#include <stack>
#include <unordered_map>
#include <utility>

using namespace std;

#define fs first
#define sc second

typedef long long ll;
typedef pair<ll, ll> P;

const ll mod = 1000000007;
ll fact[200200];
ll invfact[200200];

inline ll take_mod(ll a) { return (a % mod + mod) % mod; }

inline ll add(ll a, ll b) { return take_mod(a + b); }

inline ll sub(ll a, ll b) { return take_mod(a - b); }

inline ll mul(ll a, ll b) { return take_mod(a * b); }

inline ll powMod(ll x, ll n) {
  ll res = 1LL;
  while (n > 0) {
    if (n & 1)
      res = mul(res, x);
    x = mul(x, x);
    n >>= 1;
  }
  return res;
}

ll mod_inv(ll x) { return powMod(x, mod - 2); }

// nは上限
void make_fact(ll n) {
  fact[0] = 1;
  ll res = 1;
  for (int i = 1; i <= n; i++) {
    fact[i] = res;
    res = mul(res, i + 1);
  }
}

// nは上限
void make_invfact(ll n) {
  invfact[0] = 1;
  invfact[n] = mod_inv(fact[n]);
  for (int i = n - 1; i >= 1; i--) {
    invfact[i] = mul(invfact[i + 1], i + 1);
  }
}

ll perm(ll n, ll k) { return mul(fact[n], invfact[n - k]); }

ll comb(ll n, ll k) { return mul(mul(fact[n], invfact[n - k]), invfact[k]); }

vector<int> edge[101000];
int root2 = -1;

int dfs2(int s, int prev) {
  if (edge[s].size() == 1) {
    return s;
  } else {
    for (auto v : edge[s]) {
      if (v != prev) {
        return dfs2(v, s);
      }
    }
  }
  return -1;
}

int dfs(int s, int prev) {
  int need = edge[s].size() - 1;
  int res = 0;
  if (s != prev) {
    need--;
  }

  for (auto v : edge[s]) {
    if (v == prev) {
      continue;
    }
    int tmp = dfs(v, s);
    if (tmp > 0) {
      need--;
    }
    res += tmp;
  }
  if (need > 0) {
    res += need;
    if (root2 == -1) {
      root2 = dfs2(s, prev);
    }
  }
  return res;
}

int main() {
  int N;
  cin >> N;
  for (int i = 0; i < N - 1; i++) {
    int a, b;
    cin >> a >> b;
    edge[a].push_back(b);
    edge[b].push_back(a);
  }

  int root = -1;
  for (int i = 0; i < N; i++) {
    if (edge[i].size() == 1) {
      root = i;
      break;
    }
  }
  dfs(root, root);
  cout << dfs(root2, root2) + 1 << endl;

  return 0;
}

Fixed submission:
#include <algorithm>
#include <cstdlib>
#include <functional>
#include <iostream>
#include <limits.h>
#include <map>
#include <math.h>
#include <numeric>
#include <queue>
#include <set>
#include <stack>
#include <unordered_map>
#include <utility>

using namespace std;

#define fs first
#define sc second

typedef long long ll;
typedef pair<ll, ll> P;

const ll mod = 1000000007;
ll fact[200200];
ll invfact[200200];

inline ll take_mod(ll a) { return (a % mod + mod) % mod; }

inline ll add(ll a, ll b) { return take_mod(a + b); }

inline ll sub(ll a, ll b) { return take_mod(a - b); }

inline ll mul(ll a, ll b) { return take_mod(a * b); }

inline ll powMod(ll x, ll n) {
  ll res = 1LL;
  while (n > 0) {
    if (n & 1)
      res = mul(res, x);
    x = mul(x, x);
    n >>= 1;
  }
  return res;
}

ll mod_inv(ll x) { return powMod(x, mod - 2); }

// nは上限
void make_fact(ll n) {
  fact[0] = 1;
  ll res = 1;
  for (int i = 1; i <= n; i++) {
    fact[i] = res;
    res = mul(res, i + 1);
  }
}

// nは上限
void make_invfact(ll n) {
  invfact[0] = 1;
  invfact[n] = mod_inv(fact[n]);
  for (int i = n - 1; i >= 1; i--) {
    invfact[i] = mul(invfact[i + 1], i + 1);
  }
}

ll perm(ll n, ll k) { return mul(fact[n], invfact[n - k]); }

ll comb(ll n, ll k) { return mul(mul(fact[n], invfact[n - k]), invfact[k]); }

vector<int> edge[101000];
int root2 = -1;

int dfs2(int s, int prev) {
  if (edge[s].size() == 1) {
    return s;
  } else {
    for (auto v : edge[s]) {
      if (v != prev) {
        return dfs2(v, s);
      }
    }
  }
  return -1;
}

int dfs(int s, int prev) {
  int need = edge[s].size() - 1;
  int res = 0;
  if (s != prev) {
    need--;
  }

  for (auto v : edge[s]) {
    if (v == prev) {
      continue;
    }
    int tmp = dfs(v, s);
    if (tmp > 0) {
      need--;
    }
    res += tmp;
  }
  if (need > 0) {
    res += need;
    if (root2 == -1) {
      root2 = dfs2(s, prev);
    }
  }
  return res;
}

int main() {
  int N;
  cin >> N;
  for (int i = 0; i < N - 1; i++) {
    int a, b;
    cin >> a >> b;
    edge[a].push_back(b);
    edge[b].push_back(a);
  }

  int root = -1;
  for (int i = 0; i < N; i++) {
    if (edge[i].size() == 1) {
      root = i;
      break;
    }
  }
  dfs(root, root);
  if (root2 == -1) {
    cout << 1 << endl;
  } else {
    cout << dfs(root2, root2) + 1 << endl;
  }

  return 0;
}