题意是 如果2个人是朋友 则他们朋友的朋友也是他们的朋友 这样就组成了一圈朋友 他们就有很多朋友了 输入 2个人的名字 为2个字符串
表示2个人是朋友 并且在 同时输出他们的朋友圈有多大 注意 人数最多为100000 很多哦
显然不能用 暴力去给字符串分配编号 太大了人 那样肯定超时
就必须要用字典树了
#include<stdio.h>
#include<malloc.h>
#include<string.h>
#include<stdlib.h>
struct haha
{
struct haha *next[52];
int cnt;
};
struct haha *root;
struct haha *build()
{
struct haha *p;
int i;
p=(struct haha *)malloc(sizeof(struct haha));
for(i=0;i<52;i++)
p->next[i]=NULL;
p->cnt=0;
return p;
}
int cs,parent[200010],rank[200010];
int getnum(char *t)
{
int d,i,u;
struct haha *p;
p=root;
d=strlen(t);
for(i=0;i<d;i++)
{
if(t[i]>='a'&&t[i]<='z')
u=t[i]-'a';
else u=t[i]-'A'+26;//前面的26个位置是给小写字母留着的 不能占用 所以加26
if(p->next[u]==NULL)
{
p->next[u]=build();
p=p->next[u];
}
else p=p->next[u];
}
if(p->cnt==0) p->cnt=++cs;//走到串对应的终点了 这时候在串的末尾对应的节点上给其编号
return p->cnt; //分配的编号
}
int find(int x)
{
return x==parent[x]?x:(parent[x]=find(parent[x]));
}
void del(struct haha *p) {
int i;
for ( i=0; i<52; ++i)
{
if (p->next[i]) del(p->next[i]);
}
free(p);
p = NULL;
}
int main()
{
int cas,i,n,n1,n2;
char s1[25],s2[25];
while(scanf("%d",&cas)!=EOF)
{
while(cas--)
{
cs=0;
scanf("%d",&n);
for(i=0;i<=n+5;i++)
{
parent[i]=i;
rank[i]=1;
}
root=build();
for(i=1;i<=n;i++)
{
scanf("%s %s",s1,s2);
n1=getnum(s1);
n2=getnum(s2);
// printf("n1=%d n2=%d ",n1,n2);
n1=find(n1);
n2=find(n2);
if(n1!=n2) //
{
parent[n2]=n1;
rank[n1]+=rank[n2];//rank内的内容为当前集合的元素个数
}
printf("%d\n",rank[n1]);
}
del(root);//删除整棵树 每次都要删除整棵树 否则会错
}
}
return 0;
}