码迷,mamicode.com
首页 > 其他好文 > 详细

BZOJ 4337 树的同构

时间:2016-01-05 13:59:38      阅读:693      评论:0      收藏:0      [点我收藏+]

标签:

    很明显,这应该是一道模版题(因为我很快就在一本书上找到了这道题的模版),不过令我比较奇怪的大概是有根树和无根树的概念,以及在这道题目中根有卵用吗? (看来树这一块的知识还是要补一下)。 树的同构很明显应该是用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 }

 

BZOJ 4337 树的同构

标签:

原文地址:http://www.cnblogs.com/83131yyl/p/5102063.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!