蓝桥杯选拔F

设有一个由 n 个人组成的社团。社团中的每个成员给社团中的一个成员发送一条短信。如果有一个由社团成员组成的子社团,每个子社团中成员恰好收到一条由该子社团成员发送的短信,则称这个子社团为一个和谐子社团。和谐短信问题要求社团的最大和谐子社团。例如,设有一个由 7 个人组成的社团。将社团中的成员编号为:0,1,…,6。他们分别发送一条短信给社团成员:1,0,0,2,2,3,6。则容易看出社团成员 0,1,6 构成一个最大和谐子社团。

★算法设计: 对于给定的由 n 个人组成的社团以及社团员间发送短信的信息,设计一个计算最大和谐子社团的算法。

Input
对于每组输入数据,输入数据的第 1 行有 1 个正整数 n (1<=n<=600,000),表示社团由 n 个人组成。将社团中的成员编号为:0,1,…,n-1。第 i 个人发送一条短信给社团中成员 f (i) ,0 <= i < n ,0 <= f (i) < n 。文件的第 2 行是 f (i) 的值, 0 <= i < n 。
Output
输出计算出的社团的最大和谐子社团大小。
Sample Input
7
1 0 0 2 2 3 6
Sample Output

3

很容易发现是要选出最多的点使得每个点的入度都是1;然后就想到了以下算法:

1.把入度为0的点去掉(入度只有可能减少,不可能增加),同时把与这个点的相连的线去掉;

2.重复1,直到没有入度为0的点;

3.剩下的点集就是最大和谐子社团(入度为0的点都去掉了,所有所有点的入度比然大于等于1,又因为出度为1,所以剩下的点入度都为1)。


但是写的时候发现写不出(可能是STL的优先队列没学好,要是哪位大佬会用优先队列实现代码借在下观摩一下),然后就换了一种方法,反过来写:

1.记录入度变为0的点;

2.将入度为0的点相连的线去掉;

3重复1、2,直到没有变成入度为0的点;


#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
#include <cmath>
#include<queue>
#include<vector>

using namespace std;
typedef long long LL;
const double PI = acos(-1.0);
const double eps = 1e-6 ;
const int INF = 1e9 ;
const int maxn = 600000+10 ;
const int mod = 1000000;

int to[maxn],getCount[maxn];
int que[maxn];
void inti(int n)
{
    int i;
    for( i=0;i<=n;i++)
        getCount[i]=0;
}
int main()
{
    int n;

    int i,first,last,t,ans;
    while(~scanf("%d",&n))
    {
        inti(n);
        for( i=0;i<n;i++)
        {
            scanf("%d",&to[i]);
            getCount[to[i]]++;
        }

         first=0,last=0;
        for( i=0;i<n;i++)
        {
            if(getCount[i]==0)
                que[last++]=i;

        }

        while(first!=last)
        {
             t=que[first];
            first++;
            getCount[to[t]]--;
            if(getCount[to[t]]==0)
                que[last++]=to[t];
        }
         ans=0;
        for( i=0;i<n;i++)
        {
            if(getCount[i])
                ans++;
        }

        printf("%d\n",ans);

    }
    return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
蓝桥杯是中国著名的计算机竞赛之一,包括蓝桥杯全国软件和信息技术专业人才大赛以及蓝桥杯全国青少年程序设计比赛。其中,蓝桥杯python选拔赛是为了选拔具有优秀python编程能力的参赛者而举办的赛事。 蓝桥杯python选拔赛注重考察参赛者对python语言的理解和应用能力。在比赛中的题目往往涵盖了python编程的各个方面,包括基本语法、数据结构、算法设计和程序设计思维等。选手需要在规定的时间内,按照题目要求,使用python语言编写解决方案。 参加蓝桥杯python选拔赛可以提高参赛者的编程能力和解决问题的能力。通过参加比赛,选手们可以接触到各种不同类型的编程题目,锻炼自己的编程思维和动手能力。同时,比赛还提供了一个交流和学习的平台,选手们可以与其他参赛者分享经验、学习别人的优秀解法,提高自己的编程水平。 此外,蓝桥杯python选拔赛还是选拔参加蓝桥杯全国软件和信息技术专业人才大赛的入场券。优秀的选手将有机会代表自己的学校或单位参赛,并在比赛中展示自己的才华。 总之,蓝桥杯python选拔赛是一个提高编程水平、展示自己才能的良好平台。参加比赛不仅可以锻炼自己的编程能力,还可以结识其他编程爱好者,促进学习和交流。相信通过努力和参与,每个选手都能在蓝桥杯python选拔赛中获得进步和收获。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值