标签:
超时、超内存都碰到了。。最后还是参考了这篇博文才勉强AC
需要注意:
1. 肯定是树而不是森林,而且树的根节点一定是第一个出现的名字,所以不需要再去找哪个是根了。这样可以节省一部分内存。
2. 用并查集路径压缩的方法维护并查集结构即可,当查找的时候再压缩,不需要每次染黑节点的时候都压缩。这样可以节省一部分时间。
3. 字符串都转成id再做。
4. 能静态申请内存就尽量用静态内存,比如数组,STL少用,尤其是map,效率极低。
代码:
1 #include <iostream> 2 #include <map> 3 #include <set> 4 #include <vector> 5 #include <cstring> 6 7 using namespace std; 8 9 #define SIZE 100010 10 11 int N, M; 12 vector<int> tree[SIZE]; 13 int color[SIZE]; 14 int ancestor[SIZE]; 15 vector<pair<int, int> > query[SIZE]; 16 int ans[SIZE]; 17 map<string, int> a2i; 18 string i2a[SIZE]; 19 20 int find_gray(int node) { 21 if (color[node] == 1) 22 return node; 23 int gray = find_gray(ancestor[node]); 24 ancestor[node] = gray; 25 return gray; 26 } 27 28 void traverse(int root) { 29 color[root] = 1; 30 for (auto q : query[root]) { 31 if (ans[q.second] != 0) 32 continue; 33 if (color[q.first] == 1) 34 ans[q.second] = q.first; 35 if (color[q.first] == 2) 36 ans[q.second] = find_gray(q.first); 37 } 38 39 for (auto c : tree[root]) 40 traverse(c); 41 42 color[root] = 2; 43 } 44 45 int main() { 46 memset(color, 0, SIZE * sizeof(int)); 47 memset(ancestor, 0, SIZE * sizeof(int)); 48 memset(ans, 0, SIZE * sizeof(int)); 49 50 int order = 1; 51 cin >> N; 52 for (int i = 0; i < N; i++) { 53 string f, s; 54 int fi, si; 55 cin >> f >> s; 56 fi = a2i[f]; 57 si = a2i[s]; 58 if (fi == 0) { 59 fi = a2i[f] = order; 60 i2a[order] = f; 61 order++; 62 } 63 if (si == 0) { 64 si = a2i[s] = order; 65 i2a[order] = s; 66 order++; 67 } 68 tree[fi].push_back(si); 69 ancestor[si] = fi; 70 color[fi] = color[si] = 0; 71 } 72 cin >> M; 73 for (int i = 0; i < M; i++) { 74 string a, b; 75 int ai, bi; 76 cin >> a >> b; 77 ai = a2i[a]; 78 bi = a2i[b]; 79 query[ai].push_back(pair<int, int>(bi, i)); 80 query[bi].push_back(pair<int, int>(ai, i)); 81 } 82 83 traverse(1); 84 85 for (int i = 0; i < M; i++) 86 cout << i2a[ans[i]] << endl; 87 88 return 0; 89 }
标签:
原文地址:http://www.cnblogs.com/boring09/p/4376732.html