hihoCoder#1067 最近公共祖先·二

原题地址

 

超时、超内存都碰到了。。最后还是参考了这篇博文才勉强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 }

 

你可能感兴趣的:(code)