zoukankan      html  css  js  c++  java
  • Hourrank 21 Tree Isomorphism 树hash

    https://www.hackerrank.com/contests/hourrank-21/challenges/tree-isomorphism

    题目大意:

    给出一棵树, 求有多少本质不同的子树。   N <= 19

    下面给出我综合了网上一些做法后设计的hash函数(我不会证明碰撞概率)

    判断两棵有根树是否相同:

    将子树的Hash值从小到大排序, Hash(x) =  A * p xor Hash(son_1) mod q  * p  xor Hash(son_2) mod q ....  * p xor Hash(son_k) mod q * B mod q 

    判断两棵无根树是否相同:

    找到重心 u, v(u 可能等于v, 即只有一个重心)  分别以它们为根求有根树Hash。不妨设 Hash(u) <= Hash(v)

    Unrooted_Hash(x) = triple(n, u, v)  n为节点数。

    对于本题, 只要暴力将每个子树的Unrooted_Hash 插入到set里就好了。

    代码:

      1 //https://www.hackerrank.com/contests/hourrank-21/challenges/tree-isomorphism
      2 #include <cstdio>
      3 #include <cstring>
      4 #include <iostream>
      5 #include <cmath>
      6 #include <algorithm>
      7 #include <vector>
      8 #include <map>
      9 #include <queue>
     10 #include <set>
     11 using namespace std;
     12  
     13 typedef long long ll;
     14  
     15 #define N 20
     16 const int INF = 1 << 30;
     17 const int P = 10007, A = 31, B = 7;
     18 const ll mod = 1e12 + 22333;
     19 const double pi = acos(-1);
     20 
     21 
     22 vector<int> E[N], cone;
     23 int size[N], cnt;
     24 set<pair<int, pair<ll, ll> > > st;
     25 
     26 int DFS_SIZE(int x, int pre)
     27 {
     28     int res = 1;
     29     for (int i = 0; i < E[x].size(); ++i)
     30     {
     31         int y = E[x][i];
     32         if (y == pre) continue;
     33         res += DFS_SIZE(y, x);
     34     }
     35     return size[x] = res;
     36 }
     37 
     38 void Find_Cone(int x, int pre)
     39 {
     40     bool f = true;
     41     for (int i = 0; i < E[x].size(); ++i)
     42     {
     43         int y = E[x][i];
     44         if (y == pre) continue;
     45         Find_Cone(y, x);
     46         if (size[y] > cnt / 2) f = false;
     47     }
     48     if (cnt - size[x] > cnt / 2) f = false;
     49     if (f) cone.push_back(x);
     50 }
     51 
     52 ll Hash(int x, int pre)
     53 {
     54     vector<ll> res;
     55     for (int i = 0; i < E[x].size(); ++i)
     56     {
     57         int y = E[x][i];
     58         if (y == pre) continue;
     59         res.push_back(Hash(y, x));
     60     }
     61     sort(res.begin(), res.end());
     62     
     63     ll h = A;
     64     for (int i = 0; i < res.size(); ++i) h = (h * P ^ res[i]) % mod; 
     65     h = h * B % mod;
     66     return h;
     67 }
     68 
     69 int main()
     70 {
     71     //freopen("in.in", "r", stdin);
     72     //freopen("out.out", "w", stdout);
     73      
     74      int n, x, y, a[20], b[20];
     75      cin >> n;
     76      for (int i = 0; i < n - 1; ++i) cin >> a[i] >> b[i], --a[i], --b[i];
     77      for (int mask = 1; mask < (1 << n); ++mask)
     78      {
     79          for (int i = 0; i < n; ++i) E[i].clear(); 
     80          cone.clear(); cnt = 0;
     81          for (int i = 0; i < n - 1; ++i)
     82          {
     83              if ((mask & (1 << a[i])) && (mask & (1 << b[i])))
     84             {
     85                 E[a[i]].push_back(b[i]);
     86                 E[b[i]].push_back(a[i]);
     87             }    
     88         }
     89         int root;
     90         for (int i = 0; i < n; ++i) if (mask & (1 << i)) root = i, ++cnt;
     91         if (DFS_SIZE(root, -1) != cnt) continue;
     92         
     93         Find_Cone(root, -1);
     94         if (cone.size() == 1)
     95         {
     96             ll h = Hash(cone[0], -1);
     97             st.insert(make_pair(cnt, make_pair(h, h)));
     98         }
     99         else
    100         {
    101             ll h1 = Hash(cone[0], -1), h2 = Hash(cone[1], -1);
    102             if (h1 > h2) swap(h1, h2);
    103             st.insert(make_pair(cnt, make_pair(h1, h2)));
    104         }
    105     }
    106     printf("%d
    ", (int)st.size());
    107     return 0;
    108 } 
    View Code
  • 相关阅读:
    【每天半小时学框架】——React.js的模板语法与组件概念
    PHP中使用 $_GET 与$_POST 实现简单的前后台数据传输交互功能
    轻松几句搞定【Javascript中的this指向】问题
    跨平台移动端APP开发---简单高效的MUI框架
    JavaScript基本知识点整理(超实用)
    一款特好用的JavaScript框架——JQuery
    一个比较实用的商业级图表Echarts
    MUI顶部选项卡的用法(tab-top-webview-main)
    一个非常好用的前端JS框架-AngularJS(一)
    JavaScript面向对象中的继承
  • 原文地址:https://www.cnblogs.com/vb4896/p/6972197.html
Copyright © 2011-2022 走看看