比赛 EYOI与SBOI开学欢乐赛13th 评测结果 TWWTWWTAAWAWWWTWTWAWWWWTAATWWATW
题目名称 会合(Rendezvous) 最终得分 21
用户昵称 HeSn 运行时间 13.149 s
代码语言 C++ 内存使用 120.18 MiB
提交时间 2022-10-21 21:42:25
显示代码纯文本
  1. #include<bits/stdc++.h>
  2. using namespace std;
  3. #define int long long
  4. const int MAXN = 500010;
  5. int n, m, inc[MAXN], fa[MAXN], stp[MAXN], num[MAXN], len[MAXN], dep[MAXN], f[20][MAXN], bel[MAXN], cnt;
  6. vector<int> cd[MAXN];
  7. int find(int x) {
  8. if(x == fa[x]) {
  9. return x;
  10. }
  11. return fa[x] = find(fa[x]);
  12. }
  13. void dfs(int x, int fath, int rt) {
  14. bel[x] = rt;
  15. for(int i = 0; i < cd[x].size(); i ++) {
  16. int u = cd[x][i];
  17. if(inc[u] || u == fath) {
  18. continue;
  19. }
  20. dep[u] = dep[x] + 1;
  21. int a = find(u), b = find(x);
  22. fa[a] = b;
  23. dfs(u, x, rt);
  24. }
  25. }
  26. int lca(int x, int y) {
  27. if(dep[x] < dep[y]) {
  28. swap(x, y);
  29. }
  30. for(int i = 20; i >= 0; i --) {
  31. int u = f[i][x];
  32. if(dep[u] >= dep[y]) {
  33. x = u;
  34. }
  35. }
  36. if(x == y) {
  37. return x;
  38. }
  39. for(int i = 20; i >= 0; i --) {
  40. int u = f[i][x], v = f[i][y];
  41. if(u != v) {
  42. x = u;
  43. y = v;
  44. }
  45. }
  46. return f[0][x];
  47. }
  48. void find_circle(int x, int id, int s) {
  49. if(stp[x]) {
  50. return ;
  51. }
  52. num[x] = id;
  53. len[id] ++;
  54. stp[x] = s;
  55. find_circle(f[0][x], id, s + 1);
  56. }
  57. int check(int a, int b, int c, int d) {
  58. }
  59. signed main() {
  60. freopen("rdz.in", "r", stdin);
  61. freopen("rdz.out", "w", stdout);
  62. cin >> n >> m;
  63. for(int i = 1; i <= n; i ++) {
  64. fa[i] = i;
  65. int x;
  66. cin >> x;
  67. f[0][i] = x;
  68. cd[x].push_back(i);
  69. inc[x] ++;
  70. }
  71. queue<int> q;
  72. for(int i = 1; i <= n; i ++) {
  73. if(!inc[i]) {
  74. q.push(i);
  75. }
  76. }
  77. while(!q.empty()) {
  78. int x = q.front();
  79. q.pop();
  80. int u = f[0][x];
  81. inc[u] --;
  82. if(!inc[u]) {
  83. q.push(u);
  84. }
  85. }
  86. for(int i = 1; i <= n; i ++) {
  87. if(inc[i]) {
  88. dfs(i, 0, i);
  89. if(!stp[i]) {
  90. find_circle(i, ++ cnt, 1);
  91. }
  92. }
  93. }
  94. for(int i = 1; i <= 20; i ++) {
  95. for(int j = 1; j <= n; j ++) {
  96. f[i][j] = f[i - 1][f[i - 1][j]];
  97. }
  98. }
  99. for(int i = 1; i <= m; i ++) {
  100. int x, y;
  101. cin >> x >> y;
  102. if(find(x) != find(y)) {
  103. cout << -1 << ' ' << -1 << endl;
  104. continue;
  105. }
  106. if(bel[x] == bel[y]) {
  107. int w = lca(x, y);
  108. cout << dep[x] - dep[w] << ' ' << dep[y] - dep[w] << endl;
  109. }
  110. else {
  111. int u = bel[x], v = bel[y];
  112. int ans1 = dep[x] + (stp[v] - stp[u] + len[num[u]]) % len[num[u]];
  113. int ans2 = dep[v] + (stp[u] - stp[v] + len[num[u]]) % len[num[u]];
  114. if(check(dep[x], ans2, ans1, dep[y])) {
  115. cout << dep[x] << ' ' << ans2 << endl;
  116. }
  117. else {
  118. cout << ans1 << ' ' << dep[y] << endl;
  119. }
  120. }
  121. }
  122. return 0;
  123. }