zoukankan      html  css  js  c++  java
  • HDU5732 Subway【树重心 树哈希】

    HDU5732 Subway

    题意:

    给出两棵大小为(N)的同构树,要求输出对应的节点
    (Nle 10^5)

    题解:

    由于重心最多只有两个,找到重心之后以重心为根进行树哈希,找到相同哈希值的根之后递归输出即可
    输出儿子的时候要先对哈希值排序,保证递归进去的儿子节点也是同构的
    这里用的哈希方法是(f[u] = 1 + sum_{vin son_u}f[v]cdot prime[sz[v]])

    view code
    //#pragma GCC optimize("O3")
    //#pragma comment(linker, "/STACK:1024000000,1024000000")
    #include<bits/stdc++.h>
    using namespace std;
    function<void(void)> ____ = [](){ios_base::sync_with_stdio(false); cin.tie(0); cout.tie(0);};
    typedef uint64_t ull;
    const int MAXN = 2e5+7;
    vector<int> prime;
    void sieve(){
        vector<bool> pm(MAXN,true);
        for(int i = 2; i < MAXN; i++){
            if(pm[i]) prime.push_back(i);
            for(int j = 0; j < (int)prime.size(); j++){
                if(i*prime[j]>=MAXN) break;
                pm[i*prime[j]] = false;
                if(i%prime[j]==0) break;
            }
        }
    }
    int n;
    struct Tree{
        vector<int> G[MAXN];
        map<string,int> msk;
        string name[MAXN];
        int sz[MAXN],maxsz[MAXN];
        ull hashval[MAXN];
        int tot,root;
        void clear(){
            for(int i = 1; i <= tot; i++) G[i].clear();
            tot = 0;
            msk.clear();
        }
        int getID(string &s){
            if(!msk.count(s)){
                msk[s] = ++tot;
                name[tot] = s;
            }
            return msk[s];
        }
        void dfs(int u, int f){
            sz[u] = 1; maxsz[u] = 0;
            for(int v : G[u]){
                if(v==f) continue;
                dfs(v,u);
                sz[u] += sz[v];
                maxsz[u] = max(maxsz[u],sz[v]);
            }
            maxsz[u] = max(maxsz[u],tot-sz[u]);
        }
        void getHash(int u, int f){
            sz[u] = 1;
            hashval[u] = 1ull;
            for(int v : G[u]){
                if(v==f) continue;
                getHash(v,u);
                sz[u] += sz[v];
                hashval[u] += hashval[v] * prime[sz[v]];
            }
        }
    }tr[2];
    void match(int u0, int u1, int f0, int f1){
        cout << tr[0].name[u0] << ' ' << tr[1].name[u1] << endl;
        tr[0].hashval[f0] = UINT64_MAX;
        tr[1].hashval[f1] = UINT64_MAX;
        sort(tr[0].G[u0].begin(),tr[0].G[u0].end(),[&](const int &x, const int &y){
            return tr[0].hashval[x] < tr[0].hashval[y];
        });
        sort(tr[1].G[u1].begin(),tr[1].G[u1].end(),[&](const int &x, const int &y){
            return tr[1].hashval[x] < tr[1].hashval[y];
        });
        int m = (int)tr[0].G[u0].size() - (f0==0?0:1);
        for(int i = 0; i < m; i++)
            match(tr[0].G[u0][i],tr[1].G[u1][i],u0,u1);
    }
    void solve(){
        tr[0].clear(); tr[1].clear();
        for(int t = 0; t < 2; t++){
            for(int i = 1; i < n; i++){
                string s1, s2;
                cin >> s1 >> s2;
                int u = tr[t].getID(s1);
                int v = tr[t].getID(s2);
                tr[t].G[u].push_back(v);
                tr[t].G[v].push_back(u);
            }
        }
        tr[0].dfs(1,0);
        int hsz = *min_element(tr[0].maxsz+1,tr[0].maxsz+1+n);
        for(int i = 1; i <= n; i++){
            if(tr[0].maxsz[i]==hsz){
                tr[0].root = i;
                break;
            }
        }
        tr[0].getHash(tr[0].root,0);
        ull hax = tr[0].hashval[tr[0].root];
        tr[1].dfs(1,0);
        for(int i = 1; i <= n; i++){
            if(tr[1].maxsz[i]==hsz){
                tr[1].getHash(i,0);
                if(hax==tr[1].hashval[i]){
                    tr[1].root = i;
                    break;
                }
            }
        }
        match(tr[0].root,tr[1].root,0,0);
    }
    
    int main(){
        ____();
        sieve();
        while(cin >> n) solve();
        return 0;
    }
    
  • 相关阅读:
    AndroidStudio gradle配置
    Git中pull对比fetch和merge
    Knockout.js随手记(7)
    Knockout.js随手记(6)
    MVC自动绑定整数数组
    Knockout.js随手记(5)
    ASP.NET4.5Web API及非同步程序开发系列(3)
    Knockout.js随手记(4)
    ASP.NET4.5Web API及非同步程序开发系列(2)
    ASP.NET4.5Web API及非同步程序开发系列(1)
  • 原文地址:https://www.cnblogs.com/kikokiko/p/13191675.html
Copyright © 2011-2022 走看看