当前位置: 代码迷 >> 综合 >> 题解- [Noip2015] 信息传递
  详细解决方案

题解- [Noip2015] 信息传递

热度:79   发布时间:2024-02-05 16:47:38.0

文章目录

    • 描述
    • 解析

描述

有n个同学(编号为1到n)正在玩一个信息传递的游戏。在游戏里每人都有一个固定的信息传递对象,其中,编号
为i的同学的信息传递对象是编号为Ti同学。游戏开始时,每人都只知道自己的生日。之后每一轮中,所有人会同
时将自己当前所知的生日信息告诉各自的信息传递对象(注意:可能有人可以从若干人那里获取信息,但是每人只
会把信息告诉一个人,即自己的信息传递对象)。当有人从别人口中得知自己的生日时,游戏结束。请问该游戏一
共可以进行几轮? 简单的说就是给你一个有向图,让你找出一个最小的环来。

输入
输入共2行。
第1行包含1个正整数n表示n个人。 n ≤ 200000
第2行包含n个用空格隔开的正整数T1,T2,……,Tn
其中第i个整数Ti示编号为i的同学的信息传递对象是编号为Ti的同学,Ti≤n且Ti≠i
数据保证游戏一定会结束。

输出
输出共 1 行,包含 1 个整数,表示游戏一共可以进行多少轮。

样例
输入
5
2 4 2 3 1
输出
3


解析

创建一个环,然后依次将每个人编号存入环中,开一个数组标记,另一个数组储存编号,然后找到结果便结束,找最小的环,便是结果。

#include <bits/stdc++.h>
using namespace std;
const int maxn=200010;
int n, fa[maxn],ans=0x3f3f3f3f;
int get(int x, int &cnt){cnt++;if(fa[x]==x)return x;else return get(fa[x], cnt);
}
int main () {cin>>n;for(int i=1;i<=n;i++)fa[i]=i;for(int i=1;i<=n;i++) {int cnt=0,f;cin>>f;if(get(f,cnt)==i){ans=min(ans,cnt); }else{fa[i]=f;}}cout<<ans;return 0;
}