zoukankan      html  css  js  c++  java
  • Luogu 5043 【模板】树同构([BJOI2015]树的同构)

    BZOJ 4337

    简单记录一种树哈希的方法:以$x$为根的子树的哈希值为$sum_{y in son(x)}f_y*base_i$,$f_y$表示以$y$为根的树的哈希值,其中$i$表示$f_y$在若干个儿子中的排名,$base$是$rand$出的对一个质数取模之后的很大的数。

    对于本题这样的情况,可以每一个结点都拿出来作为根计算一下,然后再把所有的结果排个序,如果两棵树同构那么排序之后得到的序列一定是一样的。

    时间复杂度$O(n^3)$。

    Code:

    #include <cstdio>
    #include <cstring>
    #include <cstdlib>
    #include <algorithm>
    #include <vector>
    using namespace std;
    typedef long long ll;
    
    const int N = 55;
    const ll P = 1e9 + 7;
    
    int n[N], m, tot, head[N];
    ll base[N], h[N][N], f[N];
    vector <ll> g[N];
    
    struct Edge {
        int to, nxt;
    } e[N << 1];
    
    inline void add(int from, int to) {
        e[++tot].to = to;
        e[tot].nxt = head[from];
        head[from] = tot;
    }
    
    inline void read(int &X) {
        X = 0; char ch = 0; int op = 1;
        for(; ch > '9' || ch < '0'; ch = getchar())
            if(ch == '-') op = -1;
        for(; ch >= '0' && ch <= '9'; ch = getchar())
            X = (X << 3) + (X << 1) + ch - 48;
        X *= op;
    }
    
    void dfs(int x, int fat) {
        g[x].clear();
        for(int i = head[x]; i; i = e[i].nxt) {
            int y = e[i].to;
            if(y == fat) continue;
            dfs(y, x);
            g[x].push_back(f[y]);
        }
    
        if(g[x].empty()) {
            f[x] = 1LL;
            return;
        }
    
        f[x] = 0LL;
        sort(g[x].begin(), g[x].end());
        int vecSiz = g[x].size();
        for(int i = 0; i < vecSiz; i++) 
            (f[x] += g[x][i] * base[i + 1] % P) %= P;
    }
    
    inline bool chk(int x, int y) {
        for(int i = 1; i <= n[x]; i++)
            if(h[x][i] != h[y][i]) return 0;
        return 1;
    }
    
    int main() {
        srand(19260817);
        for(int i = 1; i <= 50; i++)
            base[i] = rand() * rand() % P * rand() % P * rand() % P * rand() % P;
    
        read(m);
        for(int i = 1; i <= m; i++) {
            tot = 0;
            memset(head, 0, sizeof(head));
    
            read(n[i]);
            for(int fa, j = 1; j <= n[i]; j++) {
                read(fa);
                if(fa) add(j, fa), add(fa, j);
            }
    
            for(int j = 1; j <= n[i]; j++) {
                dfs(j, 0);
                h[i][j] = f[j];
            }
            sort(h[i] + 1, h[i] + n[i] + 1);
        }
    
        for(int i = 1; i <= m; i++) {
            for(int j = 1; j <= i; j++) {
                if(n[i] != n[j]) continue;
                if(chk(i, j)) {
                    printf("%d
    ", j);
                    break;
                }
            }
        }
    
        return 0;
    }
    View Code
  • 相关阅读:
    php命令注入
    mysql事物
    安装php环境
    移除服务器缓存实例
    show user profile synchronization tools
    manual start user profile import
    JSON is undefined. Infopath Form People Picker in SharePoint 2013
    asp.net web 应用站点支持域账户登录
    Load sharepoint envirement by powershell
    sharepoint 2016 download
  • 原文地址:https://www.cnblogs.com/CzxingcHen/p/10050318.html
Copyright © 2011-2022 走看看