很明显,这应该是一道模版题(因为我很快就在一本书上找到了这道题的模版),不过令我比较奇怪的大概是有根树和无根树的概念,以及在这道题目中根有卵用吗? (看来树这一块的知识还是要补一下)。 树的同构很明显应该是用hash来判断的,当然了,不同的人设计的hash函数不同了。这道题正确的应该是要在树的重心上面跑这道题的模版,(如果你要问我树的重心是啥,我只能跟你说,如果我知道的话,下面这份代码就不会把几乎所有的点都跑一次了,但是由于N<=50,M <= 50 很明显这样跑完还是很快的,事实证明也只跑了32毫秒,但本着求真务实的心态,找个时间再补下树吧!)。很明显,尽管两棵树的形态完全相同,但如果从不同的节点开始跑这个模版,所得的hash值也会不同。所以正确的是要在几乎唯一的重心上跑(据说,一棵有根树的重心最多有两个)。加油吧!相信自己。(我是一条可耻的源程狗)。
1 #include<cstdio> 2 #include<iostream> 3 #include<vector> 4 #include<set> 5 #include<map> 6 #include<algorithm> 7 #define ull unsigned long long 8 #define magic 107ull 9 #define rep(i,j,k) for(int i = j; i <= k; i++) 10 #define maxn 60 11 using namespace std; 12 13 int read() 14 { 15 int s = 0, t = 1; char c = getchar(); 16 while( !isdigit(c) ){ 17 if( c == ‘-‘ ) t = -1; c = getchar(); 18 } 19 while( isdigit(c) ){ 20 s = s * 10 + c -‘0‘; c = getchar(); 21 } 22 return s * t; 23 } 24 25 ull pow(ull key,int n) 26 { 27 ull ret = 1ull; 28 while( n ){ 29 if( n & 1 ){ 30 ret *= key; 31 } 32 key *= key, n >>= 1; 33 } 34 return ret; 35 } 36 37 struct hash{ 38 int length; ull key; 39 40 hash(): length(0), key(0) {} 41 hash(char c): length(1), key(c) {} 42 hash(int l,ull key): length(l), key(key) {} 43 }; 44 vector<hash> childs[maxn]; 45 46 bool operator < (const hash&a, const hash&b){ 47 return a.key < b.key; 48 } 49 50 hash operator + (const hash&a, const hash& b){ 51 return hash(a.length+b.length,a.key*pow(magic,b.length)+b.key); 52 } 53 54 void operator += (hash&a,const hash&b){ 55 a = a + b; 56 } 57 58 vector<int> g[maxn]; 59 60 hash dfs(int pre,int now) 61 { 62 hash ret; 63 childs[now].clear(); int s = g[now].size(); 64 rep(i,0,s-1){ 65 int to = g[now][i]; 66 if( to == pre ) continue; 67 childs[now].push_back(dfs(now,to)); 68 } 69 sort(childs[now].begin(),childs[now].end()); 70 for(vector<hash>::iterator iter = childs[now].begin(); iter != childs[now].end(); iter++){ 71 ret += *iter; 72 } 73 ret = ‘(‘ + ret + ‘)‘; 74 return ret; 75 76 } 77 78 ull gethash(int root) 79 { 80 return dfs(-1,root).key; 81 } 82 83 set<ull> s; 84 map<ull,int> mp; 85 86 void clear() 87 { 88 rep(i,1,maxn) g[i].clear(); 89 } 90 91 int main() 92 { 93 int n = read(); 94 rep(i,1,n){ 95 clear(); s.clear(); 96 int m = read(); 97 rep(j,1,m){ 98 int x = read(); 99 if( x ) g[j].push_back(x), g[x].push_back(j); 100 } 101 bool ok = 0; 102 rep(j,1,m){ 103 ull key = gethash(j); 104 if( mp[key] ) { 105 printf("%d\n", mp[key]); 106 ok = 1; 107 break; 108 } 109 else s.insert(key); 110 } 111 if( !ok ){ 112 printf("%d\n", i); 113 for(set<ull>::iterator iter = s.begin(); iter != s.end(); iter++ ){ 114 mp[*iter] = i; 115 } 116 } 117 } 118 return 0; 119 }
时间: 2024-11-10 04:20:42