题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3172
题目大意: 找朋友,遇见新朋友就把他们的朋友圈子合并,输出总的朋友数。否则若已经在同一个,则直接输出就行。
解题思路:
明显的并查集,朋友数值需要再开一个数组存储父节点以下圈子人数,不在同一圈子合并就是。
但是敲出代码后你会果断发现TLE。网上很多解题报告也是TLE,赛后的数据藐视加强了很多。
用并查集+map暴搞明显要超时。这里就有点小技巧,对map进行指针优化处理。
1 #include <iostream>
2 #include <cstdio>
3 #include <map>
4 #include <cstring>
5 #include <algorithm>
6 using namespace std;
7
8 const int maxn=200005;
9 int pre[maxn],num[maxn];
10 char str[maxn][25];
11
12 int find(int x)
13 {
14 int r=x;
15 while(pre[r]!=r)
16 {
17 r=pre[r];
18 }
19 return r;
20 }
21
22 struct cmp
23 {
24 bool operator()(const char* s1,const char* s2)const
25 {
26 return strcmp(s1,s2)<0;
27 }
28 };
29
30 int main()
31 {
32 int T, n, fa, fb;
33 while(cin >> T)
34 {
35 while(T--)
36 {
37
38 scanf("%d",&n);
39 int cnt=0;
40 map<char*,int,cmp>M;
41 for(int i=0; i<=2*n; i++)
42 {
43 pre[i]=i;
44 num[i]=1;
45 }
46 int res=0;
47 for(int i=0; i<n; i++)
48 {
49 scanf("%s%s",str[++res],str[++res]);
50 if(!M[str[res-1]])
51 M[str[res-1]]=++cnt;
52 if(!M[str[res]])
53 M[str[res]]=++cnt;
54 fa=find(M[str[res-1]]);
55 fb=find(M[str[res]]);
56 int ans=0;
57 if(fa!=fb)
58 {
59 num[fa]+=num[fb];
60 printf("%d\n",num[fa]);
61 pre[fb]=fa;
62 }
63 else printf("%d\n",num[fa]);
64 }
65 }
66 }
67 return 0;
68 }