ZOJ 3641 <并查集+STL>
题意:
给出order数n
给出n行order<3种>
第一种:travel A m a1 .. ai .. an表示来了同学A 其中知道m个信息 信息号为a1 .. ai .. an..
第二种:share A B表示 A和B同学分享了她们共有的信息..其中信息可传递..并且和share先后无关..
第三种:check A 表示问A同学知道了多少条信息
思路:
用map<string, int> 来让同学名字变成序号..
用set来对信息去重..
用并查集使资源共享~<可节省内存~>
用set里面的size可以求的根节点的大小~即share后掌握的知识点..
Tips:
set里完成节点之间的并查后都要给子节点clear()..然后下次再找根节点的大小就好了~
Code:
View Code
1 #include <stdio.h> 2 #include <cstring> 3 #include <iostream> 4 #include <algorithm> 5 #include <map> 6 #include <set> 7 using namespace std; 8 const int MAXN = 500010; 9 10 int f[MAXN]; 11 set<int> s[MAXN]; 12 13 int find(int x) 14 { 15 return f[x]==x?x:f[x] = find(f[x]); 16 } 17 18 int main() 19 { 20 int i, j, k; 21 int n; 22 string order, name, name2; 23 int m, tmp, tot; 24 while(cin >> n) 25 { 26 for(i = 0; i <= n; ++i){ 27 f[i] = i; 28 s[i].clear(); 29 } 30 map<string, int> mm; 31 tot = 0; 32 33 for(k = 0; k < n; ++k){ 34 cin >> order; 35 if(order == "arrive"){ 36 cin >> name; 37 if(mm[name] == 0){ 38 mm[name] = ++tot; 39 } 40 41 cin >> m; 42 while(m--) 43 { 44 cin >> tmp; 45 s[mm[name]].insert(tmp); 46 } 47 } 48 else if(order == "share"){ 49 cin >> name >> name2; 50 int x = mm[name], y = mm[name2]; 51 int xx = find(x), yy = find(y); 52 if(xx != yy){ 53 f[xx] = yy; 54 set<int>::iterator it; 55 for(it = s[xx].begin(); it != s[xx].end(); ++it) 56 s[yy].insert(*it); 57 s[xx].clear(); 58 } 59 } 60 else if(order == "check"){ 61 cin >> name; 62 int x = find(mm[name]); 63 cout << s[x].size() << endl; 64 } 65 } 66 } 67 68 return 0; 69 }