hdu 3172 Virtual Friends(并查集,字典树)
题意:人与人交友构成关系网,两个人交友,相当于两个朋友圈的合并,问每个出两人,他们目前所在的关系网中的人数。
分析:用并查集,其实就是求每个集合当前的人数。对于人名的处理用到了字典树。
注意:1、题目给出的n是指n对关系,上限有2*n个人。
2、题目很没有意思的既说了有多组数据,又要求输入组数。实际上还是多组数据。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 using namespace std; 5 6 const int MAXN=200002; 7 8 struct Node{ 9 int c; 10 Node *child[52]; 11 Node(){ 12 c=0; 13 for(int i=0;i<52;i++) 14 child[i]=NULL; 15 } 16 }*root; 17 18 int cnt; 19 int p[MAXN],num[MAXN]; 20 char str1[22],str2[22]; 21 22 void init(int n) 23 { 24 root=new Node();// 25 cnt=0; 26 27 for(int i=0;i<n;i++) 28 { 29 p[i]=i; 30 num[i]=1; 31 } 32 } 33 34 int ID(char str[]) 35 { 36 Node *p=root; 37 int len=strlen(str); 38 for(int i=0,k;i<len;i++,p=p->child[k]) 39 { 40 if(str[i]>='a'&&str[i]<='z') 41 k=str[i]-'a'; 42 else 43 k=str[i]-'A'+26; 44 if(p->child[k]==NULL) 45 p->child[k]=new Node(); 46 } 47 if(p->c) 48 return p->c; 49 return p->c=++cnt;// 50 } 51 52 int find(int x) 53 { 54 return p[x]==x?x:p[x]=find(p[x]); 55 } 56 57 int main() 58 { 59 int T,n; 60 while(~scanf("%d",&T)) 61 { 62 while(T--) 63 { 64 scanf("%d",&n); 65 66 init(n*2);// 67 for(int i=0;i<n;i++) 68 { 69 scanf("%s%s",str1,str2); 70 int u=ID(str1); 71 int v=ID(str2); 72 73 int fu=find(u); 74 int fv=find(v); 75 76 if(fu==fv) 77 printf("%d\n",num[fu]); 78 else { 79 p[fv]=fu; 80 num[fu]+=num[fv]; 81 printf("%d\n",num[fu]); 82 } 83 84 } 85 } 86 } 87 return 0; 88 }