隐藏
「POJ1635」Subway tree systems - 有根树的同构 | Bill Yang's Blog

路终会有尽头,但视野总能看到更远的地方。

0%

「POJ1635」Subway tree systems - 有根树的同构

题目大意

提供两棵有根树的欧拉环游序,回答两棵树是否同构。


初步想法

有了前一道题仔细的检查的基础,此题就不难了。
还是一样的思路,求出该树的最小表示。
对于这道题完全支持$O(n^2)$的算法,故不需要把树建出来,直接对欧拉环游序进行$Hash$。
比如要求欧拉环游序$s$的最小表示,就从左往右扫描,当扫描到0和1个数相同时说明找到了一个子树,那么递归这一个子树求出其最小表示,放到数组$a[]$中。
对数组$a[]$进行排序,然后令$Hash=Size=len(s)/2+1$。
遍历数组$a[]$,使$Hash=Hash*num+a[i]$,自然溢出。
不细讲了,如果没有看懂可以参考前一题。


代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
#include<algorithm>
#include<iostream>
#include<iomanip>
#include<cstring>
#include<cstdlib>
#include<vector>
#include<cstdio>
#include<cmath>
#include<queue>
using namespace std;
typedef unsigned long long LL;
inline const int Get_Int() {
int num=0,bj=1;
char x=getchar();
while(x<'0'||x>'9') {
if(x=='-')bj=-1;
x=getchar();
}
while(x>='0'&&x<='9') {
num=num*10+x-'0';
x=getchar();
}
return num*bj;
}
LL t;
string s1,s2;
LL Hash(string s) {
if(s.length()==0)return 1;
LL sum0=0,sum1=0,pos=0,cnt=0,a[s.length()/2+1];
for(int i=0; i<s.length(); i++) {
if(s[i]=='0')sum0++;
if(s[i]=='1')sum1++;
if(sum0==sum1) {
a[++cnt]=Hash(s.substr(pos+1,i-pos-1));
pos=i+1;
}
}
sort(a+1,a+cnt+1);
LL Hash=s.length()/2+1;
for(int i=1; i<=cnt; i++)Hash=Hash*99995999+a[i];
return Hash;
}
int main() {
ios::sync_with_stdio(false);
cin>>t;
while(t--) {
cin>>s1>>s2;
if(s1.length()!=s2.length()) {
puts("different");
continue;
}
LL hash1=Hash(s1),hash2=Hash(s2);
if(hash1==hash2)puts("same");
else puts("different");
}
return 0;
}
姥爷们赏瓶冰阔落吧~
  • 本文作者: Bill Yang
  • 本文链接: https://blog.bill.moe/POJ1635/
  • 版权声明: 本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!