Problem:
Score : 800 points

Problem Statement

There is a tree with N vertices numbered 1 through N.
The i-th edge connects Vertex x_i and y_i.
Each vertex is painted white or black.
The initial color of Vertex i is represented by a letter c_i.
c_i = W represents the vertex is white; c_i = B represents the vertex is black.

A cat will walk along this tree.
More specifically, she performs one of the following in one second repeatedly:

Choose a vertex that is adjacent to the vertex where she is currently, and move to that vertex. Then, invert the color of the destination vertex.

Invert the color of the vertex where she is currently.

The cat's objective is to paint all the vertices black. She may start and end performing actions at any vertex.
At least how many seconds does it takes for the cat to achieve her objective?

Constraints

1 ≤ N ≤ 10^5

1 ≤ x_i,y_i ≤ N (1 ≤ i ≤ N-1)

The given graph is a tree.

c_i = W or c_i = B.

Input

Input is given from Standard Input in the following format:

N
x_1 y_1
x_2 y_2
:
x_{N-1} y_{N-1}
c_1c_2..c_N

Output

Print the minimum number of seconds required to achieve the objective.

Sample Input 1

5
1 2
2 3
2 4
4 5
WBBWW

Sample Output 1

5

The objective can be achieved in five seconds, for example, as follows:

Start at Vertex 1. Change the color of Vertex 1 to black.

Move to Vertex 2, then change the color of Vertex 2 to white.

Change the color of Vertex 2 to black.

Move to Vertex 4, then change the color of Vertex 4 to black.

Move to Vertex 5, then change the color of Vertex 5 to black.

Sample Input 2

6
3 1
4 5
2 6
6 1
3 4
WWBWBB

Sample Output 2

7

Sample Input 3

1
B

Sample Output 3

0

Sample Input 4

20
2 19
5 13
6 4
15 6
12 19
13 19
3 11
8 3
3 20
16 13
7 14
3 17
7 8
10 20
11 9
8 18
8 2
10 1
6 13
WBWBWBBWWWBBWWBBBBBW

Sample Output 4

21

Solution in C++ (GCC 9.2.1) (judge verdict: Accepted)

///////////////////////////////////////////////////////////////////////////////

#include <bits/stdc++.h>
#include <unistd.h>
#include <time.h>
#include <sys/time.h>

using namespace std;

///////////////////////////////////////////////////////////////////////////////

#define DEBUG 0

#define pb push_back
#define V vector
#define M unordered_map
#define S static

#define rep(i,n) for(ll i=0LL; i<n; ++i)
#define srep(i,s,n) for(ll i=s; i<n; ++i)
#define rrep(i,n) for(ll i=n-1LL; i>=0LL; --i)
#define ALL(a) (a).begin(),(a).end()
#define RALL(a) (a).rbegin(),(a).rend()
#define CIN(x) do { \
        assert(!cin.eof()); \
        cin >> x; \
        assert(!cin.fail()); \
} while(0);
#if DEBUG
#define debug_print(...) _debug_print(__VA_ARGS__)
#define debug_printf(...) printf(__VA_ARGS__)
#define debug_print_time _debug_print_time
#else // DEBUG
#define debug_print(...)
#define debug_printf(...)
#define debug_print_time
#endif // DEBUG

typedef long long ll;
typedef unsigned long long ull;
typedef tuple<ll, ll> t2;
typedef tuple<ll, ll, ll> t3;
typedef tuple<ll, ll, ll, ll> t4;
typedef tuple<ll, ll, ll, ll, ll> t5;
template <typename T>
using priority_queue_incr = priority_queue<T, V<T>, greater<T> >;

///////////////////////////////////////////////////////////////////////////////

template <typename TT, typename T>
T get_m(M<TT, T> &m, TT k, T default_value)
{
    if (m.find(k) == m.end()) return m[k] = default_value;
    return m[k];
}

template <typename TT, typename T>
void incr_m(M<TT, T> &m, TT k)
{
    if (m.find(k) == m.end()) m[k] = 0;
    m[k]++;
}

template <typename TT, typename T>
void incr_m(map<TT, T> &m, TT k)
{
    if (m.find(k) == m.end()) m[k] = 0;
    m[k]++;
}

void llin(ll &a)
{
    CIN(a);
}

void llinl1(V<ll> &v, ll count)
{
    for (ll i = 0LL; i < count; ++i) {
        ll a;
        CIN(a);
        v.push_back(a);
    }
}

void llinl2(V<t2> &v, ll count)
{
    for (ll i = 0LL; i < count; ++i) {
        ll a, b;
        CIN(a >> b);
        v.push_back(t2(a, b));
    }
}

void llinl3(V<t3> &v, ll count)
{
    for (ll i = 0LL; i < count; ++i) {
        ll a, b, c;
        CIN(a >> b >> c);
        v.push_back(t3(a, b, c));
    }
}

void llinl4(V<t4> &v, ll count)
{
    for (ll i = 0LL; i < count; ++i) {
        ll a, b, c, d;
        CIN(a >> b >> c >> d);
        v.push_back(t4(a, b, c, d));
    }
}

void llina(V<ll> &v, ll count)
{
    llinl1(v, count);
}

template <typename T>
void sort(V<T> &v)
{
    sort(v.begin(), v.end());
}

template <typename T>
void sort_reverse(V<T> &v)
{
    sort(v.begin(), v.end(), greater<T>());
}

template <typename T>
void _debug_print(T x)
{
    cout << x << endl;
}

void _debug_print(const t2 &x)
{
    ll x1 = get<0>(x);
    ll x2 = get<1>(x);
    cout << "-- " << x1 << " -- " << x2 << endl;
}

void _debug_print(const t3 &x)
{
    ll x1 = get<0>(x);
    ll x2 = get<1>(x);
    ll x3 = get<2>(x);
    cout << "-- " << x1 << " -- " << x2 << " -- " << x3 << endl;
}

void _debug_print(const t4 &x)
{
    ll x1 = get<0>(x);
    ll x2 = get<1>(x);
    ll x3 = get<2>(x);
    ll x4 = get<3>(x);
    cout << "-- " << x1 << " -- " << x2
         << " -- " << x3 << " -- " << x4 << endl;
}

template <typename T>
void _debug_print(T xarray[], ll n)
{
    rep (i, n) _debug_print(xarray[i]);
}

template <typename T>
void _debug_print(const V<T> &xlist)
{
    for (auto x : xlist) {
        cout << "-- ";
        _debug_print(x);
    }
}

template <typename T>
void _debug_print(const set<T> &xset)
{
    for (auto x : xset) {
        cout << "-- ";
        _debug_print(x);
    }
}

template <typename TT, typename T>
void _debug_print(const M<TT, T> &xlist)
{
    for (auto x : xlist) {
        TT k = x.first;
        T v = x.second;
        cout << "====" << endl;
        cout << "K=";
        _debug_print(k);
        cout << "V=";
        _debug_print(v);
    }
}

template <typename TT, typename T>
void _debug_print(const map<TT, T> &xlist)
{
    for (auto x : xlist) {
        TT k = x.first;
        T v = x.second;
        cout << "====" << endl;
        cout << "K=";
        _debug_print(k);
        cout << "V=";
        _debug_print(v);
    }
}

void _debug_print_time(const char *prefix)
{
    struct timeval tv;
    gettimeofday(&tv, NULL);
#if DEBUG
    struct tm *tm = localtime(&tv.tv_sec);
#endif
    debug_printf("-- %s %02d:%02d:%02d.%06ld\n",
                  prefix, tm->tm_hour, tm->tm_min, tm->tm_sec, tv.tv_usec);
}

///////////////////////////////////////////////////////////////////////////////

void _main();
int main()
{
    cout << setprecision(12);
#if !DEBUG
    ios::sync_with_stdio(false);
    cin.tie(0);
#endif

    _main();
    return 0;
}

void make_edgelist(const V<t2> &srclist, V<ll> edgelist[])
{
    for (auto src : srclist) {
        ll a = get<0>(src);
        ll b = get<1>(src);
        edgelist[a].pb(b);
        edgelist[b].pb(a);
    }
}

ll cnt_w(const string &colors)
{
    ll ret = 0;
    for (auto c : colors) {
        if (c == 'W') ret++;
    }
    return ret;
}

void f_longest(ll &ev, ll &ecost, const V<ll> edgelist[],
                const ll digs[], const string &colors, ll n, ll sv)
{
    queue<ll> q;
    ll costs[100005];
    rep (i, 100005) costs[i] = -1;

    ecost = 0;

    costs[sv] = 0;
    q.push(sv);

    while (q.size()) {
        ll v = q.front(); q.pop();

        if (costs[v] >= ecost && digs[v] == 1) {
            ecost = costs[v];
            ev = v;
        }

        for (auto nv : edgelist[v]) {
            if (costs[nv] >= 0) continue;
            costs[nv] = costs[v];
            if ((digs[nv] & 1LL) && colors[nv] == 'B') costs[nv] += 2LL;
            if (!(digs[nv] & 1LL) && colors[nv] == 'W') costs[nv] += 2LL;
            q.push(nv);
        }
    }

    debug_printf("sv=%lld ev=%lld ecost=%lld\n", sv, ev, ecost);
}

void _main()
{
    ll n; llin(n);
    S V<t2> xylist; llinl2(xylist, n-1);
    S string colors; CIN(colors);

    if (cnt_w(colors) <= 1) {
        cout << cnt_w(colors) << endl;
        return;
    }

    colors = '_' + colors;

    S V<ll> edgelist_orig[100005];
    make_edgelist(xylist, edgelist_orig);

    S ll digs_old[100005];
    srep (v, 1, n+1) digs_old[v] = edgelist_orig[v].size();

    S queue<ll> q;
    S bool removed[100005] = {};
    srep (v, 1, n+1) {
        if (colors[v] == 'W') continue;
        if (digs_old[v] > 1) continue;
        q.push(v);
        removed[v] = true;
    }

    while (q.size()) {
        ll v = q.front(); q.pop();
        for (auto nv : edgelist_orig[v]) {
            if (removed[nv]) continue;
            digs_old[nv]--;
            if (colors[nv] == 'W') continue;
            if (digs_old[nv] > 1) continue;
            q.push(nv);
            removed[nv] = true;
        }
    }

    debug_printf("---- removed\n");
    debug_print(removed, n+1);

    S V<ll> edgelist[100005];
    S set<ll> new_vs;
    for (auto xy : xylist) {
        ll x = get<0>(xy);
        ll y = get<1>(xy);
        if (removed[x]) continue;
        if (removed[y]) continue;
        edgelist[x].pb(y);
        edgelist[y].pb(x);
        new_vs.insert(x);
        new_vs.insert(y);
    }

    S ll digs[100005] = {};
    for (auto v : new_vs) {
        digs[v] = edgelist[v].size();
    }

    ll sv = -1;
    for (auto v : new_vs) {
        if (digs[v] == 1) {
            sv = v;
            break;
        }
    }
    assert(sv > 0);

    ll ans = (new_vs.size()-1LL) * 2LL;
    for (auto v : new_vs) {
        if ((digs[v] & 1LL) && colors[v] == 'B') ans++;
        if (!(digs[v] & 1LL) && colors[v] == 'W') ans++;
    }

    ll ev, cost;
    f_longest(ev, cost, edgelist, digs, colors, n, sv);
    f_longest(ev, cost, edgelist, digs, colors, n, ev);
    debug_printf("after f_longest ans=%lld ev=%lld cost=%lld\n", ans, ev, cost);

    ans -= cost;

    debug_printf("---- ans\n");
    cout << ans << endl;
}

///////////////////////////////////////////////////////////////////////////////