topic
Ideas
The first two are read in https://www.acwing.com/solution/content/4142/.
1
We definitely want to find the smallest representation of the two trees and see if they are the same.
In this case, we expect that each point in its subtree selects child nodes from large to small according to the longest chain length for DFS, but what if it is the same? We are going to do the same thing on the chain. In theory, I think memory search should be able to reach O (n 2) O(n^2)O ( n2 ), but I think I can't type this code even more.
2
The optimization of the previous method is to directly find the minimum representation of the child node, and then put the minimum representation of the child node in lexicographical order, and then continue to merge upwards, the minimum representation will come out, and finally judge it.
They say it is O (n 2) O(n^2)O ( n2 ), but because of the sorting, I think it is notO (n 2) O(n^2)O ( n2 )It should be slightly larger, but it won’t get stuck. (The same is true for the first one above. But if you use a similar radix sorting method, it is indeedO (n 2) O(n^2)O ( n2 ). )
3
My thinking is very violent.
p d ( x , y ) pd(x,y) pd(x,y ) means to judgex, yx,yx,y Are the two subtrees the same? How to judge? We putxxThe child nodes of x andyyThe child node of y is judged, and finally if it is found to be matched one by one, it returns1 11 , otherwise return0 00。
But how to prove the time complexity?
Obviously, for two points at the same height, at most pd pdp d once, because forpd (x, y) pd(x,y)pd(x,y ) ,xxchild nodeaa of xa和yyy 's child nodebbb will onlypd pdp d once, regardless of success or failure, the code will no longer judgepd (x, y) pd(x,y)pd(x,y ) , soa, ba, ba,b will onlypd pdeach otherp d once.
Using this, we can get the time complexity: O (n 2) O(n^2)O ( n2)
Violence works miracles! ! ! !
Code
#include<cstdio>
#include<cstring>
#define N 6100
using namespace std;
struct node
{
int y,next;
}a[N],b[N];int len,last[N],tot/*点的个数*/;
int n,fa[N],cnt[N];
void insa(int x,int y)
{
len++;
a[len].y=y;a[len].next=last[x];last[x]=len;
}
void insb(int x,int y)
{
len++;
b[len].y=y;b[len].next=last[x];last[x]=len;
}
char st[N];
int aa[N],bb[N];
int sta[N],top;//sta栈
int v[N],ts;
bool pd(int x,int y)
{
if(cnt[x]!=cnt[y])return 0;
ts++;int now=ts;
for(int k=last[x];k;k=a[k].next)
{
int xx=a[k].y,t=0;
for(int kk=last[y];kk;kk=b[kk].next)
{
int yy=b[kk].y;
if(v[yy]!=now)
{
if(pd(xx,yy)==1)
{
t=1;
v[yy]=now;break;
}
}
}
if(t==0)
{
return 0;
}
}
return 1;
}
int main()
{
int T;scanf("%d",&T);
while(T--)
{
tot=0;len=0;top=0;memset(last,0,sizeof(last));
memset(a,0,sizeof(a));memset(b,0,sizeof(b));
memset(cnt,0,sizeof(cnt));ts=0;memset(v,0,sizeof(v));
//初始化
scanf("%s",st+1);n=strlen(st+1);
for(int i=1;i<=n;i++)aa[i]=st[i]-'0';
scanf("%s",st+1);
for(int i=1;i<=n;i++)bb[i]=st[i]-'0';
sta[top]=++tot;
for(int i=1;i<=n;i++)
{
if(aa[i]==0)
{
int x=sta[top];
sta[++top]=++tot;cnt[tot]=1;
fa[tot]=x;insa(x,tot);//收一个儿子
}
else cnt[fa[sta[top]]]+=cnt[sta[top]],top--;
}
sta[top]=++tot;
for(int i=1;i<=n;i++)
{
if(bb[i]==0)
{
int x=sta[top];
sta[++top]=++tot;cnt[tot]=1;
fa[tot]=x;insb(x,tot);//收一个儿子
}
else cnt[fa[sta[top]]]+=cnt[sta[top]],top--;
}
if(pd(1,tot/2+1))printf("same\n");
else printf("different\n");
}
return 0;
}