poj 1635 树同构 记录成长历程
2012-12-11 20:48
253 查看
主要算法来自于杨弋的论文1,原始暴力代码,直接TLE
#include <iostream> #include <cstdio> #include <cstring> #define LMT 3003 using namespace std; //方法有问题,TLE char str1[LMT],str2[LMT]; int stack[LMT],len1[LMT],len2[LMT],con1[LMT],con2[LMT],tree1[LMT][LMT], tree2[LMT][LMT]; bool vis[LMT]; void dfs1(int u) { con1[u]=1; for(int i=0;i<len1[u];i++) { dfs1(tree1[u][i]); con1[u]+=con1[tree1[u][i]]; } } void dfs2(int u) { con2[u]=1; for(int i=0;i<len2[u];i++) { dfs2(tree2[u][i]); con2[u]+=con2[tree2[u][i]]; } } void kill(int u) { for(int i=0;i<len2[u];i++) vis[tree2[u][i]]=0; } void build(char str[],int len[],bool t) { int top=0,u=0,all=1; memset(len,0,sizeof(len)); for(int i=0;str[i];i++) switch(str[i]) { case '0': if(!t) tree1[u][len[u]++]=all; else tree2[u][len[u]++]=all; stack[top++]=u; u=all++; break; case '1':u=stack[--top];break; } if(!t) dfs1(0); else dfs2(0); } bool compare(int a,int b) { if(len1[a]!=len2[b]||con1[a]!=con2[b]) return 0; for(int i=0,j;i<len1[a];i++) { int x=tree1[a][i],y; for( j=0;j<len2[b];j++) if(0==vis[tree2[b][j]]) { y=tree2[b][j]; if(compare(x,y)) { vis[y]=1; break; } else kill(y); } if(j>=len2[b]) { kill(b); return 0; } } kill(b); return 1; } int main(void) { int T; scanf("%d",&T); while(T--) { scanf("%s%s",str1,str2); if(strlen(str1)!=strlen(str2)) { printf("different\n"); continue; } build(str1,len1,0); build(str2,len2,1); memset(vis,0,sizeof(vis)); if(compare(0,0)) printf("same\n"); else printf("different\n"); } return 0; }2.某大神的做法,可是那个算法对mod值取值的要求极高,至今不知道mod值的取法
#include <iostream> #include<cstdio> #include <algorithm> #define mod 19997 #define LMT 3002 using namespace std; char str1[LMT],str2[LMT]; int hash[LMT<<2]; char *p; int dfs(int u) { int sum=hash[u+LMT]; while(*p&&*p++=='0') sum=(sum+hash[u]*dfs(u+1))%mod; return (sum*sum)%mod; } void init(void) { for(int i=0;i<LMT<<2;i++) hash[i]=rand()%mod; } int main() { int T,x,y; scanf("%d",&T); init(); while(T--) { scanf("%s%s",str1,str2); p=str1; x=dfs(0); p=str2; y=dfs(0); if(x==y)printf("same\n"); else printf("different\n"); } return 0; }3.正统做法,来自”我爱橙子“的百度空间,运用论文中的方法进行赋hash值,然后对子节点排序,进行异或运算,记得异或是个重复率很小的运算
相关文章推荐
- poj 1635 Subway tree systems 判断树的同构 树的最大最小表示法模板
- 设计模式学习之路 - 序言 - 记录自己的成长历程
- 记录嵌入式软件工程师成长历程
- 开通博客,记录菜鸟的成长历程
- poj 1635 由搜索序列判断树是否同构
- poj1635_树的同构
- 地铁系统 POJ1635 subway tree systems 判断树同构 DFS搜索子串
- POJ 1635 Subway tree systems Hash法判断有根树是否同构
- 树的同构--poj 1635(有根树)ustc 1117 (无根树)
- 书籍记录了我技术的成长历程
- 第一篇 CSDN博文 记录自己的成长历程
- 树的同构 poj 1635
- 同构树的判断 poj 1635
- POJ 1635 Subway tree systems (树的同构)
- poj 1635 判断树是否同构
- 记录成长历程
- POJ1635【树的同构】【hash】
- poj-1635 Subway tree systems(判断两个有根树是否同构)-哈希法
- poj-1635 Subway tree systems(推断两个有根树是否同构)-哈希法
- 博客园----记录自己的成长历程