#P1821. 第3题-小美的红黑树
-
1000ms
Tried: 179
Accepted: 53
Difficulty: 5
所属公司 :
美团
时间 :2024年4月13日
-
算法标签>DFS
第3题-小美的红黑树
思路:树形DFS
本题其实就是统计子树中有多少个节点既有红色节点,又有黑色节点。我们可以自顶向下来进行DFS
遍历到u节点时,首先根据u节点是红/黑,来对变量进行初始化
然后我们可以遍历u的所有子节点,去将以u为根节点的红/黑节点数量进行累加计算。
最后判断以u为子树的根节点的红色和黑色节点数量是否都大于0,若大于0,则答案+1
C++
#include<bits/stdc++.h>
using namespace std;
const int N=1E5+10;
typedef long long ll;
int n,res;
string s;
vector<int>g[N];
vector<int> dfs(int u,int fa){
vector<int>color(2,0);
if(s[u]=='B')color[0]++;
else color[1]++;
for(int &x:g[u]){ //遍历子树
if(x==fa)continue;
auto v=dfs(x,u);
color[0]+=v[0];
color[1]+=v[1];
}
if(color[0]>0&&color[1]>0)res++;
return color;
}
int main(){
cin>>n;
cin>>s;
s=" "+s;
for(int i=1;i<n;i++){
int a,b;
cin>>a>>b;
g[a].push_back(b);
g[b].push_back(a);
}
dfs(1,0);
cout<<res<<endl;
return 0;
}
java
import java.util.*;
import java.io.*;
// 注意类名必须为Main
class Main {
static int n;
static Node[] nodes;
static int res = 0;
public static int aaa(){
dfs(1,new HashMap<>());
return res;
}
public static int dfs(int nodeIndex,HashMap<Integer,Integer> visited){
visited.put(nodeIndex,0);
Node node = nodes[nodeIndex];
boolean red = node.color=='R'?true:false;
boolean black = node.color=='B'?true:false;
for(int i:node.children.keySet()){
if(visited.get(i) != null){
continue;
}
int num = dfs(i,visited);
if(num == 0){
black = true;
}else if(num == 1){
red = true;
}else{
black = true;
red = true;
}
}
if(red && black){
res++;
return 2;
}
return red?1:0;
}
public static void main(String[] args) throws Exception {
// Scanner sc = new Scanner(System.in);
BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
n = Integer.parseInt(reader.readLine());
// int b = sc.nextInt();
nodes = new Node[n+1];
String s = reader.readLine();
for(int i=1;i<=n;i++){
nodes[i] = new Node();
nodes[i].color = s.charAt(i-1);
}
for(int i=1;i<n;i++){
String[] ss = reader.readLine().split(" ");
int u = Integer.parseInt(ss[0]);
int v = Integer.parseInt(ss[1]);
nodes[u].children.put(v,0);
nodes[v].children.put(u,0);
}
System.out.println(aaa());
}
}
class Node{
// int father;
HashMap<Integer,Integer> children = new HashMap<>();
char color;
}
python
import sys
sys.setrecursionlimit(200000)
n=int(input())
color = input()
adj=[[] for _ in range(n)]
for _ in range(n-1):
u,v = map(int,input().split())
adj[u-1].append(v-1)
# print(adj)
count = 0
def dfs(i):
global count
if len(adj[i])==0:
return False
flag = False
for j in adj[i]:
if dfs(j):
flag = True
else:
if color[i] != color[j]:
flag = True
if flag == True:
count +=1
return flag
dfs(0)
print(count)
题目描述
小美有一棵有n个节点的树,根节点为1号节点,树的每个节点是红色或者黑色,她想知道有多少节点的子树中同时包含红点和黑点。
输入描述
第一行输入一个整数n(1≤n≤105)表示节点数量 第二行输入一个长度为n的字符串s表示节点的颜色,第i个节点的颜色为si,若si为'B'表示节点的颜色为黑色,若si为'R' 则表示节点的颜色为红色。 接下来n−1行,每行输入两个整数 u,v(1≤u,≤n)表示树上的边.
输出描述
输出一个整数表示答案。
样例
输入
3
BRB
1 2
2 3
输出
2