字典树 Robot Game CodeChef - TR2

题目链接

Byteland是一个岛国。爱丽丝拥有构成Byteland的不同岛屿的N张地图。每个岛屿的地图由城市组成,通过道路相连。作为Byteland,每个岛屿的道路布局都是二叉树结构。每个岛屿都有一个资本,这是它的地图的二叉树的根。

爱丽丝很无聊,玩下面的游戏:
她从这N张地图中选择了k张,并在每张地图的首都放置了一个机器人。每个机器人都由一个共同的控制字符串控制。如果控制字符串的当前字符是L(R),则所有机器人移动到其地图上的左(右)子树。所有机器人都遵循相同的控制字符串,并在各自的地图上移动。

如果控制字符串对应于该地图上的有效路径,则该控制字符串对于给定的地图是有效的。如果控制字符串对于k个选定的地图中的每一个都是有效的,则认为对于给定的一组k个地图是有效的。

例如,在3个节点的完整二叉树中,控制字符串“L”和“R”是有效的,“LL”是无效控制字符串的示例。

爱丽丝有兴趣知道最长的控制字符串,对于每个k值,至少对k个地图有效。你能找到这个吗?

输入
第一行输入包含一个整数t(t <= 5),即测试用例的数量。每个测试用例都以一个整数M(1 <= M <= 100),即地图数量开始。然后M地图描述如下。
第i个地图描述以一个整数N(2 <= N <= 1000),即岛上的城市数量开始。下列N-1行中的每一行都包含两个空间分离的整数ucv(1 <= u,v <= N,c = L或R),这意味着第i个岛上的城市与城市v之间的公路,如果c是L (R),则v在u的左(右)子树中。每个岛屿的首府是一号城市。

产量
对于每个测试用例输出M空格分隔的整数,其中第i个整数表示她可以获得的最长有效控制字符串的长度,假设她可以选择i地图。

Input:
2
3
5
1 L 2
1 R 3
3 L 4
3 R 5
4
1 R 2
1 L 3
2 L 4
3
1 L 2
1 R 3
2
5
1 L 2
2 L 3
3 L 4
4 L 5
6
1 L 2
2 R 3
3 L 4
4 R 5
5 L 6

Output:
2 2 1
5 1
这里写图片描述
这里写图片描述

#include<bits/stdc++.h>
using namespace std;
const int maxn = 1e6+7;
typedef pair<int,int>pii;
vector<pii>v[1010];
int in,ans[1010];
struct trie
{
    int cnt;
    int next[2];
    int &operator[](int x)
    {
        return next[x];
    }
};
//vector数组记录左叉右叉用于dfs向下拓展
//第一个参数为字典树中的id,同时也得在dfs
//下传入字典树的父亲id
trie tree[1000010];
void add(int br,int u,int depth)
{
    for(int i=0;i<v[u].size();i++)
    {
        int x = v[u][i].second;
        if(!tree[br][x])
            tree[br][x] = in++;//开点
        int tmp = tree[br][x];
        tree[tmp].cnt++;
        ans[tree[tmp].cnt] = max( depth+1,ans[tree[tmp].cnt] );
        add(tmp,v[u][i].first,depth+1);
    }
}
int main()
{
     int t,n,m,x,y,tt;
     char ch;
     cin>>t;
     while(t--)
     {
         scanf("%d",&n);
         tt = n;
         memset(tree,0,sizeof(tree));
         memset(ans,0,sizeof(ans));
         in = 1;
         while(n--)
         {
             scanf("%d",&m);
             for(int i=1;i<=1008;i++)
                v[i].clear();
             for(int i=0;i<m-1;i++)
             {
                 scanf("%d %c %d",&x,&ch,&y);
                 v[x].push_back(pii(y,ch=='R'));
             }
             add(0,1,0);
         }
         printf("%d",ans[1]);
         for(int i=2;i<=tt;i++)
         {
             printf(" %d",ans[i]);
         }
         printf("\n");
     }
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值