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];
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· DeepSeek 开源周回顾「GitHub 热点速览」
· 记一次.NET内存居高不下排查解决与启示
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· .NET10 - 预览版1新功能体验(一)