很有趣的题目.
思路
我们考虑如果每一个栈里只有一个数怎么办。
这个时候,我们会形成一个基环树森林。
我们的操作相当于每走一步就删掉来时的路。
那么每个点最终会停在离它最近的环上的点。
我们可以发现一个性质,一个环是不会影响结果的,因为它总能走回来。
所以我们可以不断的删掉一个环,直到它变成一个树。
此时,树上的所有点的答案就都是根。
实现可以拿一个栈进行 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];
}
标签:CF1889D,int,题解,tp,st,Game,vs,100010,ns
From: https://www.cnblogs.com/JiaY19/p/18615393