BZOJ4337: BJOI2015 树的同构
2018-01-13 21:46
197 查看
题解
树哈希。因为节点可以重新标号,直接把一棵树的每一个节点当做根来做哈希再判断一下就好了。代码如下:
#include<cstdio> #include<string> #include<cstring> #include<algorithm> using namespace std; const int maxn=55,pow=2333,tt=1000000007; int m,n,tot,s[maxn],lnk[maxn],son[2*maxn],nxt[2*maxn]; long long ans[maxn][maxn]; bool vis[maxn]; void add(int x,int y){ tot++; son[tot]=y; nxt[tot]=lnk[x]; lnk[x]=tot; } long long dfs(int x){ long long w=pow; int tail=0; long long a[maxn]; for (int j=lnk[x];j;j=nxt[j]) if (vis[son[j]]==0) vis[son[j]]=1,a[++tail]=dfs(son[j]); sort(a+1,a+1+tail); for (int i=1;i<=tail;i++) w=((w*pow)%tt+a[i])%tt; return w; } void get_ans(int k,int n){ for (int i=1;i<=k;i++) { bool check=0; for (int j=1;j<=n;j++) if (ans[k][j]!=ans[i][j]) check=1; if (check==0) {printf("%d\n",i); return;} } } int main(){ scanf("%d",&m); for (int k=1;k<=m;k++) { scanf("%d",&n); s[k]=n; tot=0; memset(lnk,0,sizeof(lnk)); memset(nxt,0,sizeof(nxt)); for (int i=1;i<=n;i++) {int x; scanf("%d",&x); if (x==0) continue; add(x,i); add(i,x);} for (int i=1;i<=n;i++) { memset(vis,0,sizeof(vis)); vis[i]=1; ans[k][i]=dfs(i); } sort(ans[k]+1,ans[k]+1+n); get_ans(k,n); } return 0; }
相关文章推荐
- BZOJ4337:[BJOI2015]树的同构——题解
- 【Hash】BZOJ4337(BJOI2015)[树的同构]题解
- bzoj4337: BJOI2015 树的同构 树哈希判同构
- bzoj4337 BJOI2015 树的同构
- BZOJ4337 BJOI2015 树的同构
- bzoj4337: BJOI2015 树的同构
- BZOJ4337(BJOI2015)[树的同构]--树Hash
- bzoj4337: BJOI2015 树的同构 树hash
- BZOJ 4337 BJOI2015 树的同构 Hash
- 2017.10.6 BJOI2015 bzoj4337 树的同构
- [BZOJ4337][BJOI2015]树的同构(树的最小表示法)
- 【Hash】bzoj4337 BJOI2015树的同构
- bzoj 4337: BJOI2015 树的同构 (树hash)
- BZOJ4337 : BJOI2015 树的同构
- BZOJ 4337: BJOI2015 树的同构 树hash
- bzoj 4337: BJOI2015 树的同构 树哈希
- [树hash]BZOJ 4337——BJOI2015 树的同构
- 【树哈希】BZOJ4337 BJOI2015 树的同构
- 无根树的同构:Hash最小表示法(bzoj 4337: BJOI2015 树的同构)
- 【bzoj4337】【BJOI2015】【树的同构】【hash】