【阶段1】【AcWing 157. 树形地铁系统 1】树的最小表示

【题意】
一些主要城市拥有树形的地铁系统,即在任何一对车站之间,有且只有一种方式可以乘坐地铁。
此外,这些城市大多数都有一个中央车站。
想象一下,你是一名在拥有树形地铁系统的城市游玩的游客,你想探索该城市完整的地铁线路。
你从中央车站出发,随机选择一条地铁线,然后乘坐地铁行进。
每次到达一个车站,你都将选择一条尚未乘坐过的地铁线路进行乘坐。
如果不存在未乘坐过的线路,则退回到上一个车站,再做选择。
直到你将所有地铁线路都乘坐过两次(往返各一次),此时你将回到中央车站。
之后,你以一种特殊的方式回忆自己的坐车过程,你将你的完整地铁乘坐路线编码为一个二进制字符串。
其中0编码表示你乘坐地铁线路到达距离中央车站更远的一站,1编码表示你乘坐地铁线路到达距离中央车站更近的一站。
 
【输入格式】
第一行输入一个正整数n,代表测试用例数量。
每个测试用例由两行组成,每行输入一个由字符“0”和“1”构成的字符串,长度最多为3000, 两个字符串都描述了一种树形地铁系统的正确探索路线。
【输出格式】
对于每个测试用例,如果两个字符串描述的探索路线可以视为同一个地铁系统的两种探索路线,则输出same。
否则,输出different。
每行输出一个结果。
【输入样例】
2
0010011101001011
0100011011001011
0100101100100111
0011000111010101

  • 每一段看做一棵子树的操作,第一个数一定是0(来到这棵子树的根节点),最后一个数一定是1(回到这棵子树的根节点)
  • 每一段剥离了第一个0和最后一个1,剩下操作就是对这棵子树的每棵子树进行遍历(当第2n个数前有n个0和n个1,可知这2n个数是对一棵子树的遍历)
  • 但实际上我们只需要要递归进行子树的搜索,然后当前节点以它所有的子树为单位进行排序,合成它合法的最小遍历方式,将它的遍历方式上报给它的父亲节点,让它的父亲节点进行同样的操作,最后合成整一棵树的最小表示
  • 每棵树的最小表示唯一,比较两棵树的最小表示,即可判断两棵树是否为同一棵树
    #include <iostream>
    #include <algorithm>
    #include<cstdio>
    #include <vector>
    using namespace std;
    string dfs(string &s,int &u){
        u++;
        vector<string> v;
        while(s[u]=='0') v.push_back(dfs(s,u));
        u++;
        sort(v.begin(),v.end());
        string ans="0";
        for(string &ss:v) ans+=ss;
        ans+='1';
        return ans;
    }
    int main(){
        int t;
        cin>>t;
        while(t--){
            string a,b;
            cin>>a>>b;
            a='0'+a+'1';
            b='0'+b+'1';
            int ua=0,ub=0;
            string ra=dfs(a,ua),rb=dfs(b,ub);
            if(ra==rb) printf("same\n");
            else printf("different\n");
        }
        return 0;
    }
  •  

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值