POJ1635subway tree system

在扫描过程中一旦扫描到一个子串01数量相等了,这个时候肯定是已经递归回到根节点了,因为从根节点下去的一步操作给了一个0,而这个0一定要从这条边回到根节点才能产生一个1与其匹配(这个1不可能来自其他边的回溯,因为其他边的回溯的前提就是之前从这条边下去了,就会产生一个0,,这个0就要与这个边回溯产生的1匹配),所以就可以断开了

对同构的树来说,产生的最小表示串肯定是相等的

如果给定了最小表示串,我们能画出来的树也是唯一的(同构)

所以这是充要条件

#include<bits/stdc++.h>
#define ll long long
using namespace std;
int n;
string s1,s2;
bool cmp(string i,string j)
{
    return i<j;
}
string work(string p,int l)
{
    if(!l) return "";
    int cnt[2],num=0;
    cnt[0]=cnt[1]=0;
    vector<string> s;
    string temp="";
    for(int i=0;i<l;i++)
    {
        cnt[p[i]-'0']++;
        temp+=p[i];
        if(cnt[0]==cnt[1]) {
            s.push_back(temp);
            temp="";
        }
    } 
    num=s.size();
    for(int i=0;i<num;i++)
    {
        temp="";
        int l=s[i].length();
        for(int j=1;j<l-1;j++) temp+=s[i][j];//掐头去尾
        temp=work(temp,l-2);//一定要递归求解
        s[i]="0";
        s[i]+=temp;
        s[i]+='1';//这里一定要用+=,不要写成s[i][l-1]='1',这样不会正确识别长度
    }
    sort(s.begin(),s.end(),cmp);
    string res="";
    for(int i=0;i<num;i++) res+=s[i];
    return res; 
}
int main()
{
    scanf("%d",&n);
    while(n--)
    {
        cin>>s1>>s2;
        int l1=s1.length(),l2=s2.length(); 
        if(l1!=l2) {
            printf("different\n");
            continue;
        }
        if(work(s1,l1)==work(s2,l2)) printf("same\n");
        else printf("different\n");
    }
    return 0;
 } 

注意看里面的注释

时间复杂度\(O(n^2)\)\(n\)为节点数

posted @ 2024-01-14 20:40  最爱丁珰  阅读(1)  评论(0编辑  收藏  举报