对于每一个黑色结点,定义为一棵树的根
比如此时的路径有共4条+共3条
图片说明
那么对于一个以B为根的树
答案等于1+3 + 1*3
图片说明
也就是
图片说明
等效为
而x两两相乘求会增加复杂度,所以转换为 (x表示不含黑色结点的子树的个数,n表示该黑色结点的子树棵树)

#include <iostream>
#include <cstdio>
#include <cstring>
#include <queue>
#include <vector>
#include <map>
#include <set>
#include <cmath>
#include <algorithm>
#define ll long long
using namespace std;
const int maxn = 1e5+5;
const int inf = 0x3f3f3f3f;
int read(){
    int x=0,f=1;char ch=getchar();
    while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();}
    while(isdigit(ch)){x=x*10+ch-'0';ch=getchar();}
    return f*x;
}
char s[maxn];
std::vector<int> G[maxn];
ll sum,t1,t2,ans;
void dfs(int p,int fa){
    if(s[p] == 'B')return;
    sum++;
    for(int i = 0; i < G[p].size(); i++)
        if(G[p][i] != fa)dfs(G[p][i],p);
}
int main(){
    int n = read();
    scanf("%s",s+1);
    for(int i = 1; i < n; i++){
        int x,y;
        x = read(),y = read();
        G[x].push_back(y);
        G[y].push_back(x);
    }
    for(int i = 1; i <= n; i++){
        t1 = 0,t2 = 0;//t1黑点的所有点延续下去,连续白色的个数
        if(s[i] == 'B'){
            for(int j = 0; j < G[i].size(); j++){
                sum = 0;//表示与黑色点连接的一个点延续下去,连续白色的个数
                dfs(G[i][j],G[i][j]);
                ans += sum;
                t1 += sum;
                t2 += sum * sum;
            }
            ans += (t1 * t1 - t2)/2;
        }
    }
    printf("%lld\n",ans);
    return 0;
}