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];
}

作者:JiaY19

出处:https://www.cnblogs.com/JiaY19/p/18615393

版权:本作品采用「署名-非商业性使用-相同方式共享 4.0 国际」许可协议进行许可。

posted @   JiaY19  阅读(4)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· DeepSeek 开源周回顾「GitHub 热点速览」
· 记一次.NET内存居高不下排查解决与启示
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· .NET10 - 预览版1新功能体验(一)
more_horiz
keyboard_arrow_up light_mode palette
选择主题
menu
点击右上角即可分享
微信分享提示