bzoj4337: BJOI2015 树的同构

hash大法好

  

 

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <cstdlib>
#include <algorithm>
#define N 55
#define M 105

using namespace std;
inline int read(){
	int ret=0;char ch=getchar();
	while (ch<'0'||ch>'9') ch=getchar();
	while ('0'<=ch && ch<='9'){
		ret=ret*10-48+ch;
		ch=getchar();
	}
	return ret;
}

const int pri[49]={2,23,29,37,53,67,73,79,83,89,97,101,103,107,109,113,127,131,137,139,149,151,157,163,167,173,179,181,191,193,197,199,211,223,227,229,
233,239,241,251,257,263,269,271,277,281,283,293,307};

struct edge{
	int adj,next;
	edge(){}
	edge(int _adj,int _next):adj(_adj),next(_next){}
} e[M];
int n,g[N],m;
void AddEdge(int u,int v){
	e[++m]=edge(v,g[u]);g[u]=m;
	e[++m]=edge(u,g[v]);g[v]=m;
}

unsigned int data[N];
bool vis[N];
void dfs(int u){
	vis[u]=1;
	int p=0;
	unsigned int d[N];
	d[p++]=1;
	for (int i=g[u];i;i=e[i].next){
		int v=e[i].adj;
		if (vis[v]) continue;
		dfs(v);
		d[p++]=data[v];
	}
	sort(d,d+p);
	data[u]=0;
	for (int i=0;i<p;++i) data[u]+=d[i]*pri[i];
}


int num[N];
unsigned int hash[N][N];

int main(){
	int tot=read();
	for (int j=1;j<=tot;++j){
		n=num[j]=read();
		int root;
		memset(g,0,sizeof(g));m=1;
		for (int i=1;i<=n;++i){
			int fa=read();
			if (fa) AddEdge(fa,i);
		}
		for (int i=1;i<=n;++i){
			memset(vis,0,sizeof(vis));
			dfs(i);
			hash[j][i]=data[i];
		}
		sort(hash[j]+1,hash[j]+n+1);
		for (int i=1;i<=j;++i)
			if (num[i]==num[j]){
				int k=1;
				for (;k<=n;++k) if (hash[i][k]!=hash[j][k]) break;
				if (k>n){
					printf("%d\n",i);
					break;
				}
			}
	}
	
	return 0;
}

  

posted @ 2016-01-14 11:36  wangyurzee  阅读(436)  评论(0编辑  收藏  举报