#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函数写的
树同构未过~~hdu5732(超时)
最新推荐文章于 2020-03-11 21:09:59 发布