Problem p03358 (C++)

Buggy submission (status: Time Limit Exceeded):
#include <algorithm>
#include <iostream>
#include <vector>
using namespace std;

int N, A[100009], B[100009], dp[100009], par[100009], L[100009], G[100009],
    dist1[100009], dist2[100009];
char c[100009];
vector<int> X[100009], Y[100009];

void dfs(int pos) {
  dp[pos] = 1;
  if (c[pos] == 'B')
    dp[pos] = 0;
  for (int i = 0; i < X[pos].size(); i++) {
    if (dp[X[pos][i]] >= 0)
      continue;
    dfs(X[pos][i]);
    dp[pos] += dp[X[pos][i]];
    par[X[pos][i]] = pos;
  }
}

void dfs1(int pos, int depth) {
  if (dist1[pos] >= 0)
    return;
  dist1[pos] = depth;
  for (int i = 0; i < Y[pos].size(); i++) {
    int cost = 0;
    if (G[Y[pos][i]] == 1)
      cost = 1;
    dfs1(Y[pos][i], depth + cost);
  }
}
void dfs2(int pos, int depth) {
  if (dist2[pos] >= 0)
    return;
  dist2[pos] = depth;
  for (int i = 0; i < Y[pos].size(); i++) {
    int cost = 0;
    if (G[Y[pos][i]] == 1)
      cost = 1;
    dfs2(Y[pos][i], depth + cost);
  }
}

int main() {
  cin >> N;
  int D = 0;
  for (int i = 1; i <= N - 1; i++) {
    cin >> A[i] >> B[i];
    X[A[i]].push_back(B[i]);
    X[B[i]].push_back(A[i]);
  }
  for (int i = 1; i <= N; i++) {
    cin >> c[i];
    if (c[i] == 'W')
      D++;
    dp[i] = -1;
  }
  dfs(1);
  int sum = 0, t = 0;
  for (int i = 1; i <= N; i++) {
    int S = D;
    bool OK = false;
    for (int j = 0; j < X[i].size(); j++) {
      if (par[i] == X[i][j])
        continue;
      if (dp[X[i][j]] == D)
        OK = true;
      S -= dp[X[i][j]];
    }
    if (S == D && c[i] == 'B')
      OK = true;
    if (OK == false) {
      L[i] = 1;
      t = i;
    }
  }
  if (t == 0) {
    cout << "0" << endl;
    return 0;
  }
  for (int i = 1; i <= N - 1; i++) {
    if (L[A[i]] == 1 && L[B[i]] == 1) {
      Y[A[i]].push_back(B[i]);
      Y[B[i]].push_back(A[i]);
      sum += 2;
    }
  }
  if (sum == 0) {
    cout << "1" << endl;
    return 0;
  }
  for (int i = 1; i <= N; i++) {
    if (Y[i].size() % 2 == 1 && c[i] == 'B') {
      sum++;
      G[i] = 1;
    }
    if (Y[i].size() % 2 == 0 && c[i] == 'W') {
      sum++;
      G[i] = 1;
    }
  }
  if (N <= 10000) {
    int maxn = 0;
    for (int i = 1; i <= N; i++) {
      for (int j = 1; j <= N; j++)
        dist1[j] = -1;
      dfs1(i, G[i]);
      for (int j = 1; j <= N; j++)
        maxn = max(maxn, dist1[j]);
    }
    cout << sum - maxn * 2 << endl;
  } else {
    for (int i = 1; i <= N; i++) {
      dist1[i] = -1;
      dist2[i] = -1;
    }
    dfs1(t, G[1]);
    int maxn = -1, maxid = -1;
    for (int i = 1; i <= N; i++) {
      if (maxn < dist1[i]) {
        maxn = dist1[i];
        maxid = i;
      }
    }
    dfs2(maxid, G[maxid]);
    int maxn2 = 0;
    for (int i = 1; i <= N; i++)
      maxn2 = max(maxn2, dist2[i]);
    cout << sum - maxn2 * 2 << endl;
  }
  return 0;
}

Fixed submission:
#include <algorithm>
#include <iostream>
#include <vector>
using namespace std;

int N, A[100009], B[100009], dp[100009], par[100009], L[100009], G[100009],
    dist1[100009], dist2[100009];
char c[100009];
vector<int> X[100009], Y[100009];

void dfs(int pos) {
  dp[pos] = 1;
  if (c[pos] == 'B')
    dp[pos] = 0;
  for (int i = 0; i < X[pos].size(); i++) {
    if (dp[X[pos][i]] >= 0)
      continue;
    dfs(X[pos][i]);
    dp[pos] += dp[X[pos][i]];
    par[X[pos][i]] = pos;
  }
}

void dfs1(int pos, int depth) {
  if (dist1[pos] >= 0)
    return;
  dist1[pos] = depth;
  for (int i = 0; i < Y[pos].size(); i++) {
    int cost = 0;
    if (G[Y[pos][i]] == 1)
      cost = 1;
    dfs1(Y[pos][i], depth + cost);
  }
}
void dfs2(int pos, int depth) {
  if (dist2[pos] >= 0)
    return;
  dist2[pos] = depth;
  for (int i = 0; i < Y[pos].size(); i++) {
    int cost = 0;
    if (G[Y[pos][i]] == 1)
      cost = 1;
    dfs2(Y[pos][i], depth + cost);
  }
}

int main() {
  cin >> N;
  int D = 0;
  for (int i = 1; i <= N - 1; i++) {
    cin >> A[i] >> B[i];
    X[A[i]].push_back(B[i]);
    X[B[i]].push_back(A[i]);
  }
  for (int i = 1; i <= N; i++) {
    cin >> c[i];
    if (c[i] == 'W')
      D++;
    dp[i] = -1;
  }
  dfs(1);
  int sum = 0, t = 0;
  for (int i = 1; i <= N; i++) {
    int S = D;
    bool OK = false;
    for (int j = 0; j < X[i].size(); j++) {
      if (par[i] == X[i][j])
        continue;
      if (dp[X[i][j]] == D)
        OK = true;
      S -= dp[X[i][j]];
    }
    if (S == D && c[i] == 'B')
      OK = true;
    if (OK == false) {
      L[i] = 1;
      t = i;
    }
  }
  if (t == 0) {
    cout << "0" << endl;
    return 0;
  }
  for (int i = 1; i <= N - 1; i++) {
    if (L[A[i]] == 1 && L[B[i]] == 1) {
      Y[A[i]].push_back(B[i]);
      Y[B[i]].push_back(A[i]);
      sum += 2;
    }
  }
  if (sum == 0) {
    cout << "1" << endl;
    return 0;
  }
  for (int i = 1; i <= N; i++) {
    if (Y[i].size() % 2 == 1 && c[i] == 'B') {
      sum++;
      G[i] = 1;
    }
    if (Y[i].size() % 2 == 0 && c[i] == 'W') {
      sum++;
      G[i] = 1;
    }
  }
  if (N <= 1000) {
    int maxn = 0;
    for (int i = 1; i <= N; i++) {
      for (int j = 1; j <= N; j++)
        dist1[j] = -1;
      dfs1(i, G[i]);
      for (int j = 1; j <= N; j++)
        maxn = max(maxn, dist1[j]);
    }
    cout << sum - maxn * 2 << endl;
  } else {
    for (int i = 1; i <= N; i++) {
      dist1[i] = -1;
      dist2[i] = -1;
    }
    dfs1(t, G[1]);
    int maxn = -1, maxid = -1;
    for (int i = 1; i <= N; i++) {
      if (maxn < dist1[i]) {
        maxn = dist1[i];
        maxid = i;
      }
    }
    dfs2(maxid, G[maxid]);
    int maxn2 = 0;
    for (int i = 1; i <= N; i++)
      maxn2 = max(maxn2, dist2[i]);
    cout << sum - maxn2 * 2 << endl;
  }
  return 0;
}