题意
思路
前提:建树用的是 vector<PII> v[N] 代表着 u:{v1,i} {v2,i} {v3,i} i为编号,u->v是一条边
我们先假设把这颗树建完
令f[u]代表u节点需要经历多少次这样
之后dfs它们,观察它们出现的次序,如果v比u先出现就得 f[v] = f[u] + 1 否则 f[v] = f[u]
最后输出最大的f就行
代码
// https://codeforces.com/problemset/problem/1900/C **1300**
// 复杂度应该是O(n) 判断只有左边和右边需要加return否则复杂度爆炸
#include<iostream>
#include<cstdio>
#include<stack>
#include<vector>
#include<algorithm>
#include<cmath>
#include<cstring>
#include<map>
#include<set>
#include<queue>
#include<vector>
#define IOS ios::sync_with_stdio(0);cin.tie(0);cout.tie(0)
#define ft first
#define sd second
#define int long long
//#define i8 __int128
#define endl '\n'
#define ull unsigned long long
using namespace std;
typedef long long ll;
const double pi = acos(-1.0); //圆周率
const int mod = 1e9 + 7;
const int INF = 1e18;
const int N = 2e5 + 10;
typedef pair<int, int> PII;
int n;
string st;
void solve()
{
cin >> n >> st;
st = " " + st;
vector<PII> ve(n+1);
int x,y;
for(int i = 1;i <= n;i ++)
{
cin >> x >> y;
ve[i] = {x,y};
}
int minid = INF;
auto dfs = [&] (auto dfs,int u,int cnt) -> void
{
if(ve[u].first == 0 && ve[u].second == 0)
{
minid = min(minid,cnt);
return;
}
// 如果出现U
if(st[u] == 'U')
{
// 就有什么走什么
if(ve[u].first != 0)
{
dfs(dfs,ve[u].first,cnt + 1);
}
if(ve[u].second != 0)
{
dfs(dfs,ve[u].second,cnt + 1);
}
}
// 只能在左边走
if(ve[u].first != 0 && st[u] == 'R' && ve[u].second == 0)
{
dfs(dfs,ve[u].first,cnt + 1);
return;
}
// 只能在右边走
if(ve[u].second != 0 && st[u] == 'L' && ve[u].first == 0)
{
dfs(dfs,ve[u].second,cnt + 1);
return;
}
// 左右都能走
if(ve[u].first != 0 || ve[u].second != 0)
{
// 如果必须往左走
if(st[u] == 'L')
{ // 原来free 有改动+1
if(ve[u].first != 0) dfs(dfs,ve[u].first,cnt);
if(ve[u].second != 0) dfs(dfs,ve[u].second,cnt + 1);
}
if(st[u] == 'R')
{ // 同上
if (ve[u].second != 0) dfs(dfs,ve[u].second,cnt);
if (ve[u].first != 0) dfs(dfs,ve[u].first,cnt + 1);
}
}
};
dfs(dfs,1,0);
cout << minid << endl;
}
signed main()
{
IOS;
int _ = 1; cin >> _;
while (_--) solve();
return 0;
}