树同构未过~~hdu5732(超时)

#include<iostream>//未过原因我估计是我c++关于字符串的语法很差吧。。
#include<cstdio>
#include<algorithm>
#include<map>
#include<string>
#include<string.h>
using namespace std;
typedef long long ll;
const ll a = 12289;
const ll b = 40961;
const ll p = 233333333;
const ll q = 998244353;
int n;
map<string, int>name[2];
int temphash[10010];
struct edgee
{
	int to;
};
int first[2][10020];
int nextt[2][20020];
edgee edge[2][20020];
int edgetot[2];
struct diann
{
	char name[11];
	ll hashh;
};
diann dian[2][10020];
int diantot[2];
char temp[30];
char temp1[20];
char temp2[20];
void readd(int kind,int &a,int &b)
{
	int i = 0; int lena;
	int j = 0; int lenb;
	for (j = 0; temp[j] != ' '; j++)
		temp1[i++] = temp[j];
	j++;
	lena = i;
	temp1[i] = '\0';
	i = 0;
	for (; temp[j] != '\0'; j++)
		temp2[i++] = temp[j];
	lenb = i;
	temp2[i] = '\0';
	if (name[kind].find(temp1) == name[kind].end())
	{
		for (int i = 0; i < lena; i++)
			dian[kind][diantot[kind]].name[i] = temp1[i];
		name[kind][temp1] = diantot[kind]++;
	}
	a = name[kind][temp1];
	if (name[kind].find(temp2) ==name[kind].end())
	{
		for (int i = 0; i < lenb; i++)
			dian[kind][diantot[kind]].name[i] = temp2[i];
		name[kind][temp2] = diantot[kind]++;
	}
	b = name[kind][temp2];
}
void addedge(int from, int to, int kind)
{
	edge[kind][edgetot[kind]].to = to;
	nextt[kind][edgetot[kind]] = first[kind][from];
	first[kind][from] = edgetot[kind]++;
	edge[kind][edgetot[kind]].to = from;
	nextt[kind][edgetot[kind]] = first[kind][to];
	first[kind][to] = edgetot[kind]++;
}
int size[2][10010];
int root[2][2],maxnum[2][2];
void getroot(int num, int kind,int fa)
{
	size[kind][num] = 1;
	int maxx = 1;
	for (int i = first[kind][num]; i != -1; i = nextt[kind][i])
	{
		int to = edge[kind][i].to;
		if (to == fa)
			continue;
		getroot(to, kind,num);
		size[kind][num] += size[kind][to];
		maxx = max(maxx, size[kind][to]);
	}
	maxx = max(maxx, n - size[kind][num]);
	if (maxx < maxnum[kind][0])
	{
		root[kind][0] = num;
		maxnum[kind][0] = size[kind][num];
		root[kind][1] = -1; maxnum[kind][1] = -1;
	}
	else
	{
		if (maxx == maxnum[kind][0])
			root[kind][1] = num,maxnum[kind][1]=maxx;
	}
}
ll gethash(int kind, int num,int fa)
{
	 int htot = 0;
	for (int i = first[kind][num]; i != -1; i = nextt[kind][i])
	{
		int to = edge[kind][i].to ;
		if (to == fa)
			continue;
		temphash[htot++] = gethash(kind, to,num);
	}
	if (nextt[kind][first[kind][num]] == -1)
		return 1;
	sort(temphash, temphash + htot);
	dian[kind][num].hashh = ((a*p) ^ (temphash[0])) % q;
	for (int i = 1; i < htot; i++)
	{
		dian[kind][num].hashh = ((dian[kind][num].hashh*p) ^ (temphash[i])) % q;
	}
	return dian[kind][num].hashh = (dian[kind][num].hashh*b) % q;
}
bool com1(diann a, diann b)
{
	return a.hashh < b.hashh;
}
void solve()
{
	getroot(0, 0, -1);
	ll temphash = gethash(0, root[0][0], -1);
	getroot(0, 1, -1);
	ll temphash1 = gethash(1, root[1][0], -1);
	if (temphash1 != temphash)
		gethash(1, root[1][1], -1);
	sort(dian[0], dian[0] + diantot[0], com1);
	sort(dian[1], dian[1] + diantot[1], com1);
	for (int i = 0; i < n; i++)
	{
		printf("%s %s\n", dian[0][i].name, dian[1][i].name);
	}
}

int main()
{
		while (scanf("%d", &n) != EOF)
	{
		getchar();
		for (int i = 0; i < 2; i++)
			for (int j = 0; j < 2; j++)
			{
			maxnum[i][j] = -1;
			root[i][j] = -1;
			}
		for (int i = 0; i < 2; i++)
		{
			diantot[i] = 0; edgetot[i] = 0; name[i].clear();
			for (int j = 0; j <= n; j++)
			{
				first[i][j] = -1;
			}
		}
		for (int i = 1; i < n; i++)
		{
			int a, b;
			gets(temp);
			readd(0, a, b);
			addedge(a, b, 0);
		}
		for (int i = 1; i < n; i++)
		{
			int a, b;
			gets(temp);
			readd(1, a, b);
			addedge(a, b, 1);
		}
		solve();
	}
}
用杨割里的论文的hash函数写的
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值