BZOJ4337: BJOI2015 树的同构(hash 树同构)
程序员文章站
2022-05-19 18:03:46
题意 "题目链接" Sol 树的同构问题,直接拿hash判一下,具体流程大概是这样的: 首先转化为有根树,预处理出第$i$棵树以$j$为根时的hash值。 那么两个树同构当且仅当把两棵树的hash数组排完序后完全一致(感性理解一下) cpp / / include define Pair pair ......
题意
sol
树的同构问题,直接拿hash判一下,具体流程大概是这样的:
首先转化为有根树,预处理出第\(i\)棵树以\(j\)为根时的hash值。
那么两个树同构当且仅当把两棵树的hash数组排完序后完全一致(感性理解一下)
/* */ #include<bits/stdc++.h> #define pair pair<int, int> #define mp(x, y) make_pair(x, y) #define fi first #define se second #define ll long long #define ull unsigned long long using namespace std; const int maxn = 51, mod = 1e9 + 7; const ull base = 997; inline int read() { char c = getchar(); int x = 0, f = 1; while(c < '0' || c > '9') {if(c == '-') f = -1; c = getchar();} while(c >= '0' && c <= '9') x = x * 10 + c - '0', c = getchar(); return x * f; } int n, ha[maxn][maxn], fa[maxn], ans[maxn], top, num[maxn]; ull st[maxn], f[maxn]; vector<int> v[maxn]; ull dfs(int x, int fa) { vector<int> st; f[x] = 1; for(int i = 0; i < v[x].size(); i++) { int to = v[x][i]; if(to == fa) continue; st.push_back(dfs(to, x)); } sort(st.begin(), st.end()); for(int i = 0; i < st.size(); i++) f[x] = base * f[x] + st[i]; return f[x]; } bool check(int a, int b) { if(num[a] != num[b]) return 0; for(int i = 1; i <= num[a]; i++) if(ha[a][i] != ha[b][i]) return 0; return 1; } signed main() { n = read(); for(int i = 1; i <= n; i++) { num[i] = read(); for(int j = 1; j <= num[i]; j++) v[j].clear(); for(int j = 1; j <= num[i]; j++) { fa[j] = read(); if(fa[j]) v[fa[j]].push_back(j), v[j].push_back(fa[j]); } for(int j = 1; j <= num[i]; j++) ha[i][j] = dfs(j, 0); sort(ha[i] + 1, ha[i] + num[i] + 1); } for(int i = 1; i <= n; i++) { ans[i] = i; for(int j = 1; j <= i - 1; j++) if(check(j, i)) {ans[i] = j; break;} } for(int i = 1; i <= n; i++) printf("%d\n", ans[i]); return 0; } /* 4 4 2 0 2 3 4 0 1 1 2 4 0 1 1 1 4 0 1 2 3 */
上一篇: 最新权威回答 结婚证丢了能离婚吗