Friend
Friend
| Time Limit: 1000MS | Memory Limit: 65535KB |
| Submissions: 102 | Accepted: 10 |
Sample Input
4 2 Hilary Dearway 1 Hilary 2 Rusty Serena 2 Serena Luoxi 10 2 a b 2 b c 1 c 3 a d e 2 e f 2 f g 2 g h 2 h i 2 j k 1 z
Sample Output
2 3
解析:
题意:问有多少个不相关的朋友圈
思路:这是一道不错的并查集问题,其中牵扯到字符串的记录,
①可以用字典树记录字符串,最后还是要返回编号,基于题目中的“每个字符串由52个大小写英文字母及数字组成且长度小于10”
②用C++中的
#include <map>
#include <sttring>
map<string,int>mymap;
将字符串转成数字,便于记录
然后其他的其实跟基本并查集一样,初始化、统一父结点,代码如下:
# include<iostream> # include<cstring> # define N 100005 using namespace std; int parent[N]; int cnt; struct node { int flag; int num; node *next[126]; node() { memset(next,NULL,sizeof(next)); flag=0; } }; //node *root=new node; void Init() { int i; for(i=0;i<10005;i++) parent[i]=i; } int find(int a) { if(a!=parent[a]) { parent[a]=find(parent[a]); } return parent[a]; } void Union(int s,int e) { int root_s,root_e,temp; root_s=find(s); root_e=find(e); if(root_s<root_e) { temp=root_s; root_s=root_e; root_e=temp; } if(root_s!=root_e) { parent[root_s]=root_e; } } int Transfor(char s[],struct node *root)//这里用的是字典树来记录的 { int i,x; int len=strlen(s); node *p=root; for(i=0;i<len;i++) { x=s[i]-'0'; if(p->next[x]==NULL) p->next[x]=new node; p=p->next[x]; } if(p->flag==1)//出现过 return p->num; else { p->flag=1; p->num=cnt; cnt++; } return p->num; } /*void Clear() { memset(root->next,NULL,sizeof(root->next)); }*/ int main() { int nCase,nNum,sign,i,leap; char str[30]; while(cin>>nCase) { node *root=new node; cnt=0; leap=0; Init(); while(nCase--) { cin>>nNum; for(i=0;i<nNum;i++) { cin>>str; if(i==0) sign=Transfor(str,root); else { Union(sign,Transfor(str,root));//统一父结点 } } } for(i=0;i<cnt;i++) { if(find(i)!=i)leap++;//用find(i)==i来判断,效果一样 } cout<<cnt-leap<<endl; // Clear(); delete root; } return 0; }
浙公网安备 33010602011771号