比较基础的并查集,求集合所含元素的个数,中间用字典树给出现过的名字标号
View Code
#include<iostream>
#include<algorithm>
#include<string>
#define MAXN 100000+10
using namespace std;
int f[MAXN],r[MAXN],n,num;
typedef struct node
{
int cnt;
struct node *next[52];
}*tree,Trie;
tree root;
inline int GetNum(char *t)//用字典树对字符串编号
{
tree p = root,newnode;
for(int i = 0;i < strlen(t); ++i)
{
int u;
if(t[i]>='a' && t[i]<='z')
u = t[i] - 'a';
else u= t[i]-'A'+26;
if(p->next[u]==NULL)
{
newnode=(tree)malloc(sizeof(Trie));
newnode->cnt=-1;
for(int j=0;j<52;j++)
newnode->next[j]=NULL;
p->next[u]=newnode;
p=newnode;
}
else
p = p->next[u];
}
if(p->cnt == -1) //该节点未出现过
p->cnt = num ++;
return p->cnt;
}
void init()
{
for(int i=0;i<MAXN;i++)
{
f[i]=i;
r[i]=1;
}
root=(tree)malloc(sizeof(Trie));
root->cnt=-1;
for(int j=0;j<52;j++)
root->next[j]=NULL;
num=0;
}
int find(int x)
{
if(x==f[x])
return f[x];
f[x]=find(f[x]);
return f[x];
}
int Union(int x,int y)
{
int a=find(x);
int b=find(y);
if(a==b) return r[a];
if(r[a]>r[b])
{
r[a]+=r[b];
r[b]=0;
f[b]=a;
return r[a];
}
r[b]+=r[a];
r[a]=0;
f[a]=b;
return r[b];
}
int main()
{
int T,a,b;
char s1[30],s2[30];
while(scanf("%d",&T)!=EOF)
{
while(T--)
{
scanf("%d",&n);
init();
for(int i=0;i<n;i++)
{
scanf("%s %s",s1,s2);
a=GetNum(s1);
b=GetNum(s2);
printf("%d\n",Union(a,b));
}
}
}
return 0;
}