【蓝桥2018省赛】小朋友崇拜圈

【蓝桥2018省赛】小朋友崇拜圈

在这里插入图片描述
在这里插入图片描述

标签:dfs,枚举

思路:

首先看懂题目,样例中输入的3 4 2 5…这些代表什么,他们代表的是1号同学崇拜3号,2号崇拜4号,题目说可以自己崇拜自己,比如9号就是**自恋狂**,崇拜自己。

要找最大的圈,即要成环才行,最后一个数应该回到开始的那个第一个数,比如2 3 4 5 ,由2开始,经过4 5 3,最后一个数是2,这样搜索结束,可以记录和更新答案

dfs流程:

我们从1开始,把1标记 1指向3,标记3 3指向2,标记2 2—>4—>5—>3—>2,每经过的点都被标记过了,我们发现标记过的点在2又重复了,而且最后一个数的开始的数不相等,可以return了,回溯,他会一步一步回退,沿着来时的路回退,回退过程中没有可以继续搜索的点了,那么最终回退到1,从1为起点的搜索结束,接下来搜索2,直到搜索完毕**,记住回退过程中要恢复状态**

#include<bits/stdc++.h>
using namespace std;
int n;
const int N=1e5+5;
int a[N];
int sum=-1;
int c;
int vis[N];//记录状态,全局变量默认为0,那么我们设定0为未访问,1为访问过
void dfs(int m,int u)
{   
    if(c==m){sum=max(sum,u);return;}//第一个和最后一个数字一样,成环了,更新答案,回溯
    if(!vis[m]) {vis[m]=1;dfs(a[m],u+1);vis[m]=0;}//vis[m]为0,未访问,进行下一次搜索
    if(vis[m])return;//没成环,而且被搜过了,那说明不能形成崇拜圈,回溯
}
int main()
{
  cin>>n;
  for(int i=1;i<=n;i++)
  {
    cin>>a[i];
  }
  for(int i=1;i<=n;i++)
  {
     c=i;//记录下我们的开始点
     vis[i]=1;//状态更改
     dfs(a[i],1);//第一个代表我们的i号人崇拜的对象,1代表搜索了1个
     vis[i]=0;//恢复状态
  }
  cout<<sum;
}
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值