题目描述
有一天,maki拿到了一颗树。所谓树,即没有自环、重边和回路的无向连通图。
这个树有 n个顶点,n - 1 条边。每个顶点被染成了白色或者黑色。
maki想知道,取两个不同的点,它们的简单路径上有且仅有一个黑色点的取法有多少?
注:
①树上两点简单路径指连接两点的最短路。
② <p,q>和 <q,p>的取法视为同一种。
输入描述:
第一行一个正整数 n 。代表顶点数量(1 <= n <= 100000)。 第二行是一个仅由字符'B'和'W'组成的字符串。第 i个字符是B代表第 i个点是黑色,W代表第 i 个点是白色。 接下来的 n - 1 行,每行两个正整数 x , y ,代表 x 点和 y 点有一条边相连 (1 <= x,y <= n)
输出描述:
一个正整数,表示只经过一个黑色点的路径数量。
输入:
3 WBW 1 2 2 3
输出:
3
只需要我们判断一个黑色的点与多少个白色的点相连,然后算出有多少条路就OK了
#include <iostream>
#include <cstring>
#include <vector>
using namespace std;
const int N = 1e5 + 10;
int n;
char g[N];
vector<int>v[N];
int dfs(int u,int fa)
{
if(g[u] == 'B')return 0;
int cnt = 0;
for(auto &x : v[u])
{
if(x == fa)continue;
cnt += dfs(x,u);
}
return cnt + 1;
}
int main()
{
cin >> n;
cin >> g + 1;
for(int i = 0;i < n - 1;i ++)
{
int a,b;
cin >> a >> b;
v[a].push_back(b);
v[b].push_back(a);
}
long long ans = 0;
for(int i = 1;i <= n;i ++)
{
if(g[i] == 'B')
{
long long sum = 0;
for(auto &x : v[i])
{
int cnt =dfs(x,i);
ans = ans + sum * cnt + cnt;
sum += cnt;
}
}
}
cout << ans << endl;
return 0;
}