P5043 【模板】树同构([BJOI2015]树的同构)

P5043 【模板】树同构([BJOI2015]树的同构)
思路:树hash,先找树重心,重心最多两个,然后从以重心为根求出树的hash值,放进map里。
代码:

#pragma GCC optimize(2)
#pragma GCC optimize(3)
#pragma GCC optimize(4)
#include<bits/stdc++.h>
using namespace std;
#define y1 y11
#define fi first
#define se second
#define pi acos(-1.0)
#define LL long long
//#define mp make_pair
#define pb push_back
#define ls rt<<1, l, m
#define rs rt<<1|1, m+1, r
#define ULL unsigned LL
#define pll pair<LL, LL>
#define pli pair<LL, int>
#define pii pair<int, int>
#define piii pair<pii, int>
#define pdd pair<double, double>
#define mem(a, b) memset(a, b, sizeof(a))
#define debug(x) cerr << #x << " = " << x << "\n";
#define fio ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
//head
 
const ULL B = 133;
int n, m, f, sz[55], hz;
vector<int> g[55], rt;
unordered_map<ULL, int> mp0;
map<pair<ULL, ULL>, int> mp1;
void get_h(int u, int o) {
    sz[u] = 1;
    int mx = 0;
    for (int v : g[u]) {
        if(v != o){
            get_h(v, u);
            sz[u] += sz[v];
            mx = max(mx, sz[v]);    
        }
    }
    mx = max(mx, n-sz[u]);
    if(mx < hz) vector<int>().swap(rt), rt.pb(u), hz = mx;
    else if(mx == hz) rt.pb(u);
}
ULL dfs(int u, int o) {
    sz[u] = 1;
    vector<ULL> vc;
    for (int v : g[u]) {
        if(v != o) {
            vc.pb(dfs(v, u));
            sz[u] += sz[v];
        } 
    }
    if(vc.size() == 0) return 1;
    sort(vc.begin(), vc.end());
    ULL t = 1, sum = 0;
    for (ULL x:vc) {
        sum += t*x;
        t *= B; 
    } 
    return sum*sz[u];
}
int main() {
    scanf("%d", &m);
    for (int cs = 1; cs <= m; ++cs) {
        scanf("%d", &n);
        int r;
        for (int i = 1; i <= n; ++i) {
            scanf("%d", &f);    
            if(!f) r = i;
            else g[f].pb(i), g[i].pb(f); 
        }
        hz = n;
        get_h(r, r);
        assert(rt.size() <= 2);
        assert(rt.size() >= 1); 
        if(rt.size() == 2) {
            ULL a = dfs(rt[0], rt[0]);
            ULL b = dfs(rt[1], rt[1]);
            if(a > b) swap(a, b);
            if(mp1.find({a, b}) != mp1.end()) printf("%d\n", mp1[{a, b}]);
            else mp1[{a, b}] = cs, printf("%d\n", cs); 
        } 
        else {
            ULL a = dfs(rt[0], rt[0]);
            if(mp0.find(a) != mp0.end()) printf("%d\n", mp0[a]);
            else mp0[a] = cs, printf("%d\n", cs); 
        } 
        vector<int>().swap(rt);
        for (int i = 1; i <= n; ++i) vector<int>().swap(g[i]);
    }
    return 0;
} 
上一篇:菜鸟的Xamarin.Forms前行之路——windows下VS运行ios模拟器调试


下一篇:反对称 Antisymmetry