E - Transition Game(拓扑排序)

该文章介绍了一个涉及序列A的二人游戏,玩家Takahashi和Aoki进行多轮比赛。每轮中,Aoki选择次数Ki,Takahashi选择一个数字Si并在黑板上书写。若按照A[i]的值作为下标反复替换,经过Ki次后到达数字i,则Takahashi获胜。关键在于识别环的存在,Takahashi在环上可确保胜利。文章通过拓扑排序找出环中的数字,从而确定胜负策略。
摘要由CSDN通过智能技术生成

传送门

题意 :

        给定一个长度为 N 的序列 A,使得每个 A[i] 都满足 1≤A[i]≤N。

 

        Takahashi 和 Aoki 将玩 N 轮游戏。

        对于每一轮游戏,Aoki 会指定一个正整数 Ki,然后 Takahashi 会选择一个整数 Si,在黑板上写下它,并重复进行 Ki 次以下操作:

        将黑板上的数值 x 替换为 A[x]。 如果在第 Ki 次操作后黑板上写的是数字 i,则 Takahashi 获胜,否则 Aoki 获胜。

注意,对于每轮游戏,Takahashi 和 Aoki 都是为了自己获胜而采取最优策略。 

 思路分析:

       对于每一个数字 i ,我们需要求出它是否可以让 T 获胜 。根据题意,可以发现是让我们把数字沿着值作为下标 再到 下一个值, 这样看就是一张单点出度为1 存在环的图。

        对于每一轮的操作的数字 即为 i 。

        对于T:T的目的是让 路径的目标点为 i,如果i 在一个环上则T 可以逆向找到距离目标点 i 有 Ki步的地方出发,这样T就必胜了。

        对于  A: A的目标是让i不在终点,那就是说不让i出现在环上面。

        综上 对所有在环上的点i,T必胜;不在环上的点,A必胜。

一想到环就可以用拓扑排序来处理,找到在环上的点,问题就解决了。

        

 


#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int M = 2e5 + 5;
const ll mod = 100003;
int a[M],d[M],n;
queue<int>q;
vector<int>v[M];
void topsort(){
   for(int i=1;i<=n;i++)if(!d[i])q.push(i);
   while (!q.empty()){
      int x=q.front();
      q.pop();
      for(auto y:v[x]){
         if(--d[y]==0)q.push(y);
      }
   }
   return ;
   
}
void solve()
{
   cin>>n;int res=0;

   for(int i=1;i<=n;i++){
      cin>>a[i];
      v[i].push_back(a[i]);
      d[a[i]]++;
   }
   topsort();
   for(int i=1;i<=n;i++){
      if(d[i])res++;
   }
   cout<<res<<endl;
   
return ;
}
int  main()
{
   int t = 1;
   // cin >> t;
   while (t--)
   {
      solve();
   }
   return 0;
}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值