nikolaj

alina

May 22nd, 2015
297
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 2.97 KB | None | 0 0
  1. #include <algorithm>
  2. #include <iostream>
  3. #include <utility>
  4. #include <vector>
  5. #include <stack>
  6.  
  7. using std::vector;
  8. using std::stack;
  9. using std::cerr;
  10. using std::cout;
  11. using std::pair;
  12. using std::swap;
  13. using std::cin;
  14. using std::min;
  15.  
  16. using vint = vector<int>;
  17. using vbool = vector<bool>;
  18. using Graph = vector<vint>;
  19.  
  20.  
  21. void add_edge(Graph &a, int u, int v) {
  22. a[u].push_back(v);
  23. a[v].push_back(u);
  24. }
  25.  
  26. void paint(vint &color, stack<int> &q, int &col, int v) {
  27. for (int u = -1; u != v;) {
  28. u = q.top();
  29. color[u] = col;
  30. q.pop();
  31. }
  32. col++;
  33. }
  34.  
  35. void dfs(const Graph &a, vbool &used, stack<int> &q, vint &even, vint &color, vint &ret, int &tim, int &col, int v, int p = -1) {
  36. tim++;
  37. used[v] = true;
  38. q.push(v);
  39. even[v] = tim;
  40. ret[v] = tim;
  41. for (auto to : a[v]) {
  42. if (to == p) {
  43. continue;
  44. }
  45. if (used[to]) {
  46. ret[v] = min(ret[v], even[to]);
  47. } else {
  48. dfs(a, used, q, even, color, ret, tim, col, to, v);
  49. ret[v] = min(ret[v], ret[to]);
  50. if (ret[to] > even[v]) {
  51. paint(color, q, col, to);
  52. }
  53. }
  54. }
  55. }
  56.  
  57. int lca(const vector<vint> &parent, const vint &height, int u, int v) {
  58. if (height[v] < height[u]) {
  59. swap(v, u);
  60. }
  61. for (int w = (int) parent[v].size() - 1; w >= 0; w--) {
  62. if (height[parent[v][w]] >= height[u]) {
  63. v = parent[v][w];
  64. }
  65. }
  66. if (u == v) {
  67. return u;
  68. }
  69. for (int w = (int) parent[v].size() - 1; w >= 0; w--) {
  70. if (parent[v][w] != parent[u][w]) {
  71. v = parent[v][w];
  72. u = parent[u][w];
  73. }
  74. }
  75. return parent[v][0];
  76. }
  77.  
  78. int main() {
  79. size_t n, m;
  80. cin >> n >> m;
  81. size_t f;
  82. cin >> f;
  83. f--;
  84. Graph a(n);
  85. for (size_t i = 0; i < m; i++) {
  86. int u, v;
  87. cin >> u >> v;
  88. add_edge(a, u - 1, v - 1);
  89. }
  90. vbool used(n, false);
  91. stack<int> q;
  92. vint even(n, -1);
  93. vint ret(n, -1);
  94. vint color(n, -1);
  95. int tim = 0, col = 0;
  96. dfs(a, used, q, even, color, ret, tim, col, f);
  97. paint(color, q, col, f);
  98. int k = 0;
  99. while ((1 << k) <= col) k++;
  100. f = color[f];
  101. vector<vint> parent((size_t) col, vint((size_t) k, f));
  102. for (size_t i = 0; i < n; i++) {
  103. for (auto to : a[i]) {
  104. int u = color[i];
  105. int v = color[to];
  106. if (u > v) {
  107. parent[v][0] = u;
  108. }
  109. }
  110. }
  111. vint height((size_t) col, 0);
  112. for (int i = col - 2; i >= 0; i--) {
  113. height[i] = height[parent[i][0]] + 1;
  114. }
  115. for (int w = 0; w + 1 < k; w++) {
  116. for (int i = 0; i < col; i++) {
  117. parent[i][w + 1] = parent[parent[i][w]][w];
  118. }
  119. }
  120. int qn;
  121. cin >> qn;
  122. for (int i = 0; i < qn; i++) {
  123. int u, v;
  124. cin >> u >> v;
  125. int s = lca(parent, height, color[u - 1], color[v - 1]);
  126. cout << height[s] << "\n";
  127. }
  128. return 0;
  129. }
Advertisement
Add Comment
Please, Sign In to add comment