第九届蓝桥杯 ——小朋友崇拜圈

问题描述
班里 N N N 个小朋友,每个人都有自己最崇拜的一个小朋友(也可以是自己)。

在一个游戏中,需要小朋友坐一个圈,每个小朋友都有自己最崇拜的小朋友在他的右手边。

求满足条件的圈最大多少人?小朋友编号为 1 , 2 , 3 , . . . N 1,2,3,...N 1,2,3,...N

输入格式
第一行,一个整数 N N N 3 < N < 1 0 5 3 < N < 10^5 3<N<105
第二行 N N N 个整数,由空格分开。

输出格式
要求输出一个整数,表示满足条件的最大圈的人数。

样例输入1
9
3 4 2 5 3 8 4 6 9

样例输出1
4

解释
如图所示,崇拜关系用箭头表示,红色表示不在圈中。

显然,最大圈是 [ 2 , 4 , 5 , 3 ] [2,4,5,3] [2,4,5,3] 构成的圈

在这里插入图片描述

样例输入2
30
22 28 16 6 27 21 30 1 29 10 9 14 24 11 7 2 8 5 26 4 12 3 25 18 20 19 23 17 13 15

样例输出2
16


题解:拓扑排序

解题思路:先用拓扑排序去掉所有不成环的点,那么剩下的点都能找到对应的环,最后遍历所有环,取最大值即可。

#include <bits/stdc++.h>
using namespace std;

const int N = 100010;

int n, ans;
int d[N], admire[N];
bool used[N], check[N];

void dfs(int u, int len)
{
    if(used[u])
    {
        ans = max(ans, len);
        return;
    }
    used[u] = true;
    dfs(admire[u], len + 1);
}

void topsort()
{
    queue<int> q;
    memset(check, true, sizeof check);
        
    for (int i = 1; i <= n; i ++)   
        if(d[i] == 0)
        {
            q.push(i);
            check[i] = false;
        }

    while(q.size())
    {
        int a = q.front(); q.pop();
        int b = admire[a];
        if(--d[b] == 0) 
        {
            q.push(b);
            check[b] = false;
        }
    }
}

int main()
{
    cin >> n;
    for (int i = 1; i <= n; i ++) 
    {
        scanf("%d", &admire[i]);
        d[admire[i]] ++;
    }
    
    topsort();

    for (int i = 1; i <= n; i ++)
        if(check[i] && !used[i])
            dfs(i, 0);
        
    cout << ans << endl;
    return 0;
}

蓝桥杯C/C++省赛历年题

  • 3
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值