题解- [Noip2015] 信息传递

文章目录

    • 描述
    • 解析

描述

有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 
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<

你可能感兴趣的:(题解)