Loading

CF1889D Game of Stacks 题解

很有趣的题目.

思路

我们考虑如果每一个栈里只有一个数怎么办。

这个时候,我们会形成一个基环树森林。

我们的操作相当于每走一步就删掉来时的路。

那么每个点最终会停在离它最近的环上的点。

我们可以发现一个性质,一个环是不会影响结果的,因为它总能走回来。

所以我们可以不断的删掉一个环,直到它变成一个树。

此时,树上的所有点的答案就都是根。

实现可以拿一个栈进行 dfs。

Code

#include <bits/stdc++.h>
using namespace std;

int n, tp;
int ns[100010];
int st[100010];
int vs[100010];
vector<int> to[100010];

inline int dfs(int x) {
  if (ns[x]) return ns[x];
  if (vs[x]) {
    do {
      vs[st[tp]] = 0, tp--;
    } while (st[tp + 1] != x);
  }
  vs[st[++tp] = x] = 1;
  if (to[x].empty()) return x; 
  int y = to[x].back();
  to[x].pop_back();
  return dfs(y);
}

int main() {
  ios::sync_with_stdio(0), cin.tie(0);
  cin >> n;
  for (int i = 1; i <= n; i++) {
    int k;
    cin >> k;
    to[i].resize(k);
    for (int j = 0; j < k; j++)
      cin >> to[i][j];
  }
  for (int i = 1; i <= n; i++) {
    if (ns[i]) continue;
    int s = dfs(i);
    while (tp) {
      ns[st[tp]] = s, tp--;
    }
  }
  for (int i = 1; i <= n; i++) cout << ns[i] << " \n"[i == n];
}
posted @ 2024-12-18 16:58  JiaY19  阅读(22)  评论(0)    收藏  举报