树的同构--poj 1635(有根树)ustc 1117 (无根树)
2012-10-04 21:37
507 查看
只有一个点入度为0的树是外向树,只有一个点出度为0的树是内向树,这两种是典型的有根树
平时见到的无向图中的树是无根树
1.判断树同构本质是哈希,每个点的权值是这个点的子树的权值和,这里所谓的权值是随机数产生的
由于随机性,树上某一组合不同都会导致最终的结果不一样,所以只要判断根的权值是否相等就可以确定同构
2.随机性决定了不确定性,但正确率还是很高
3.可以不用哈希,用“最小表示”表示出一个点的子节点,再比较最小表示产生的序列是否相同,代码烦,比较复杂,不见得快
poj 1635
ustc 1117
平时见到的无向图中的树是无根树
1.判断树同构本质是哈希,每个点的权值是这个点的子树的权值和,这里所谓的权值是随机数产生的
由于随机性,树上某一组合不同都会导致最终的结果不一样,所以只要判断根的权值是否相等就可以确定同构
2.随机性决定了不确定性,但正确率还是很高
3.可以不用哈希,用“最小表示”表示出一个点的子节点,再比较最小表示产生的序列是否相同,代码烦,比较复杂,不见得快
poj 1635
#include <iostream> #include <cstdlib> #include <cstring> #include <cstdio> #include <cmath> using namespace std; #define mod 9997 char str1[10000]; char str2[10000]; int h[10000],len,cur; char *p; int hashing(int j) { int sum=h[j]; while(*p!='\0'&&*p++=='0') //每次检查是否1时还加1,使回溯时跳出循环 { sum=(sum+hashing(j+1)*h[j])%mod; } return (sum*sum)%mod; } int main () { for(int i=0;i<10000;++i) h[i]=rand()%mod; int test;scanf("%d",&test); while(test--) { scanf("%s%s",str1,str2); if(strlen(str1)!=strlen(str2)) { printf("different\n"); continue; } len=strlen(str1); p=str1; int a=hashing(1); p=str2; int b=hashing(1);// 多次hash 可以避免冲突,提高正确率 if(a==b) printf("same\n"); else printf("different\n"); } system("pause"); return 0; }
ustc 1117
#include <iostream> #include <cstring> #include <cstdio> #include <cstdlib> #include <cmath> #include <vector> using namespace std; #define mod 9973 int h[1050]; vector<int>s[1050]; vector<int>p[1050]; int vis[1050]; int n; int Hash(int cur,int depth) { int sum=h[depth];vis[cur]=1; for(int i=0;i<s[cur].size();++i) if(!vis[s[cur][i]]) sum=(sum+Hash(s[cur][i],depth+1)*h[depth])%mod; return (sum*sum)%mod; } int Hash2(int cur,int depth) { int sum=h[depth];vis[cur]=1; for(int i=0;i<p[cur].size();++i) if(!vis[p[cur][i]]) sum=(sum+Hash2(p[cur][i],depth+1)*h[depth])%mod; return (sum*sum)%mod; } int main () { for(int i=0;i<1040;++i) h[i]=rand()%mod; int test;scanf("%d",&test); while(test--) { scanf("%d",&n); for(int i=1;i<=n;++i) s[i].clear(),p[i].clear(); int u,v; for(int i=1;i<n;++i) { scanf("%d%d",&u,&v); s[u].push_back(v); s[v].push_back(u); } for(int i=1;i<n;++i) { scanf("%d%d",&u,&v); p[u].push_back(v); p[v].push_back(u); } memset(vis,0,sizeof(vis)); int a=Hash(1,1); bool flag=false; for(int i=1;i<=n;++i) { memset(vis,0,sizeof(vis)); int b=Hash2(i,1); if(a==b) flag=true; if(flag) break; } if(flag) printf("same\n"); else printf("different\n"); } system("pause"); return 0; }
相关文章推荐
- poj-1635 Subway tree systems(判断两个有根树是否同构)-哈希法
- poj-1635 Subway tree systems(推断两个有根树是否同构)-哈希法
- 地铁系统 POJ1635 subway tree systems 判断树同构 DFS搜索子串
- poj 1635 Subway tree systems 判断树的同构 树的最大最小表示法模板
- poj 1635 Subway tree systems(树的同构,经典)
- POJ 1635 Subway tree systems(HASH+判断两棵有根树是否同构)
- 同构树的判断 poj 1635
- poj 1635 Subway tree systems (树同构)
- POJ 1635 Subway tree systems(树同构)
- poj 1635 由搜索序列判断树是否同构
- poj 1635( 树的最小表示法判断同构 )
- poj1635_树的同构
- POJ 1635 Subway tree systems Hash法判断有根树是否同构
- POJ1635【树的同构】【hash】
- POJ 1635 Subway tree systems (树的同构)
- 【有根树的同构】ZOJ 1990/POJ 1635
- poj 1635 树同构 记录成长历程
- poj 1635 判断树是否同构
- 树的同构 poj 1635
- POJ 1635 Subway tree systems