Codeforces Round 911 C. Anji‘s Binary Tree

原题:

C. Anji's Binary Tree

time limit per test

2.5 seconds

memory limit per test

256 megabytes

input

standard input

output

standard output

Keksic keeps getting left on seen by Anji. Through a mutual friend, he's figured out that Anji really likes binary trees and decided to solve her problem in order to get her attention.

Anji has given Keksic a binary tree with n vertices. Vertex 1 is the root and does not have a parent. All other vertices have exactly one parent. Each vertex can have up to 2 children, a left child, and a right child. For each vertex, Anji tells Keksic index of both its left and its right child or tells him that they do not exist.

Additionally, each of the vertices has a letter s i s_i si on it, which is either 'U', 'L' or 'R'.

Keksic begins his journey on the root, and in each move he does the following:

复制代码
If the letter on his current vertex is 'U', he moves to its parent. If it doesn't exist, he does nothing.
If the letter on his current vertex is 'L', he moves to its left child. If it doesn't exist, he does nothing.
If the letter on his current vertex is 'R', he moves to its right child. If it doesn't exist, he does nothing. 

Before his journey, he can perform the following operations: choose any node, and replace the letter written on it with another one.

You are interested in the minimal number of operations he needs to do before his journey, such that when he starts his journey, he will reach a leaf at some point. A leaf is a vertex that has no children. It does not matter which leaf he reaches. Note that it does not matter whether he will stay in the leaf, he just needs to move to it. Additionally, note that it does not matter how many times he needs to move before reaching a leaf.

Help Keksic solve Anji's tree so that he can win her heart, and make her come to Čačak.

Input

Each test consists of multiple test cases. The first line contains a single integer t

(1≤t≤ 5 ⋅ 1 0 4 5⋅10^4 5⋅104) --- the number of test cases. The description of test cases follows.

The first line of each test case contains a single integer n

(2≤n≤ 3 ⋅ 1 0 5 3⋅10^5 3⋅105) --- the number of vertices in a tree.

The second line of each test case contains a string s

of n characters --- characters are written on the vertices. It is guaranteed that s

consists only of characters 'U', 'L', and 'R'.

The i-th of the next n lines contains two integers li and ri (0≤li,ri≤n) --- indices of left and right child of the vertex i. If l i l_i li=0, it means that vertex i does not have a left child. If r i r_i ri=0, it means that vertex i does not have a right child. It is guaranteed that this data describes a valid binary tree rooted at 1

.

It is guaranteed that the sum of n

over all test cases does not exceed 3 ⋅ 1 0 5 3⋅10^5 3⋅105.

Output

For each test case, output a single integer --- the minimal number of operations Keksic needs to do to reach a leaf.

Example

Input

Copy

5

3

LRU

2 3

0 0

0 0

3

ULR

3 2

0 0

0 0

2

LU

0 2

0 0

4

RULR

3 0

0 0

0 4

2 0

7

LLRRRLU

5 2

3 6

0 0

7 0

4 0

0 0

0 0

Output

Copy

0

1

1

3

1

Note

In the first test case, vertex 1

has 2 as its left child and 3 as its right child. Vertices 2 and 3 do not have children and are therefore leaves. As 'L' is written on vertex 1, Keksic will go to vertex 2, therefore he has to do no operations.

In the second test case, vertex 1

has 3 as its left child and 2 as its right child. Vertices 2 and 3 are leaves. As 'U' is written on vertex 1

, Keksic needs to change it to either 'L' or 'R' in order for him to reach a leaf.

In the third case, vertex 1

has only a right child, which is vertex 2. As 'L' is written on it, Keksic needs to change it to 'R', otherwise he would be stuck on vertex 1

.

In the fourth case, he can change 3

characters so that letters on the vertices are "LURL", which makes him reach vertex 2

.

In the fifth case, there are 3

leaves, 3, 6 and 7. To reach either leaf 6 or leaf 7, he needs to change 2 characters. However, if he changes character on vertex 1 to 'R', he will reach leaf 3, therefore the answer is 1

中文:

给你一个二叉树,每个节点上要么有字母L要么有字母R要么有字母U,你从根节点出发,如果使遇到字母U就不动,遇到字母L就走左子树,遇到字母R就走右子树。现在让你走到一个叶子节点,走的过程中可以把节点上的字母替换成自己想要的,问你最少替换多少次能走到一个叶子节点。

代码:

cpp 复制代码
    #include <bits/stdc++.h>
    using namespace std;
    const int maxn = 3e5 + 2;
    struct node {
        int lch, rch;
    };
    node ns[maxn];
    int dp[maxn];
    bool vis[maxn];
    char s[maxn];
    int t, n;
     
    int bfs() {
        queue<int> Q;
        memset(vis, false, sizeof(vis));
        memset(dp, 0, sizeof(dp));
        int ans = INT_MAX;
        Q.push(1);
        vis[1] = true;
        while(!Q.empty()) {
            int cur = Q.front();
            Q.pop();
            int lch = ns[cur].lch;
            int rch = ns[cur].rch;
            if (lch != 0) {
                if (s[cur] == 'L') {
                    dp[lch] = dp[cur];
                }
                if (s[cur] == 'R' || s[cur] == 'U') {
                    dp[lch] = dp[cur] + 1;
                }
                Q.push(lch);
            }
            if (rch != 0) {
                if (s[cur] == 'R') {
                    dp[rch] = dp[cur];
                }
                if (s[cur] == 'L' || s[cur] == 'U') {
                    dp[rch] = dp[cur] + 1;
                }
                Q.push(rch);
            }
            if (lch == 0 && rch == 0) { // 此时叶子节点
                ans = min (ans, dp[cur]);
            }
        }
        return ans;
    }
     
    int main() {
        ios::sync_with_stdio(false);
        cin >> t;
        while (t--) {
            cin >> n;
            cin >> s + 1;
            for (int i = 1; i <= n; i++) {
                cin >> ns[i].lch >> ns[i].rch;
            }
            int ans = bfs();
            cout << ans << endl;
        }
        return 0;
    }

解答:

简单的树形dp,要找从根节点到某一个叶子节点替换字符最少。广搜根节点到每个节点的距离,维护一个dp数组,记录当前节点所需要替换字符的最少次数。
d p c u r dpcur dpcur 表示 到达 编号为cur的节点时最少的替换字符数,如果cur节点不是叶子节点,且字母是L,那么 d p l e f t _ c h i l d ( c u r ) = d p c u r dpleft\\_child(cur) = dpcur dpleft_child(cur)=dpcur,left_child(cur)表示 cur节点左孩子的编号。否则,就要在dpcur上加一,因为要改变一次字母。

相关推荐
小超人诞生日记31 分钟前
C++ 智能指针的使用及其原理详解
c++·算法
AiNightVision4 小时前
无人机夜视模块如何选择?——从参数指标到系统集成的完整选型指南
人工智能·算法·计算机视觉·车载系统·无人机·视频·智能硬件
牧羊人.3335 小时前
卷积神经网络之VGG
人工智能·深度学习·神经网络·算法·cnn
小郎君6585 小时前
Vue 多标签页的加载态设计:为什么我没有用 Suspense 实现 PageLoading
vue.js·算法
JJJennie7776 小时前
MAI Gateway私有化部署全攻略:大模型网关如何接入?附架构图
算法·gateway·ai网关·魔芋ai
東隅已逝,桑榆非晚6 小时前
算法3.双指针法-快乐数
c++·笔记·学习·算法
专注仿真6 小时前
卷积神经网络(CNN)算法详解
人工智能·python·算法·代码·大模型训练
FII工业富联科技服务6 小时前
多智能体如何进入制造现场?从业务协同到数字孪生验证
大数据·人工智能·算法·机器人·制造·数字孪生
≮傷£≯√6 小时前
httpserver_QNetWorkClient
算法
Evand J6 小时前
【PMSM例程11】永磁同步电机(PMSM)基于UKF的转速与转子位置估计。附下载链接
算法·matlab·卡尔曼滤波·永磁同步电机·ukf·pmsm·位置估计