[蓝桥杯][2018年第九届真题]小朋友崇拜圈

题目链接:小朋友崇拜圈



解题思路:先用拓扑思想,把度为0的点删除,因为环里的点度都是为1的,也把度为0的点相连的点的度-1,如果还是为0则也不是在环里,最后剩下的肯定是环,然后循环找每个环的大小即可

#include<bits/stdc++.h>
#define x first
#define y second
#define mem1(h) memset(h,-1,sizeof h)
#define mem0(h) memset(h,0,sizeof h)
#define mcp(a,b) memcpy(a,b,sizeof b)
using namespace std;
typedef long long LL;
typedef unsigned long long ull; 
typedef pair<int,int>PII;
typedef pair<double,double>PDD;
namespace IO{
    
    
	inline LL read(){
    
    
		LL o=0,f=1;char c=getchar();
		while(c<'0'||c>'9'){
    
    if(c=='-')f=-1;c=getchar();}
		while(c>='0'&&c<='9'){
    
    o=o*10+c-'0';c=getchar();}
		return o*f;
	}
}using namespace IO;
//#############以上是自定义技巧(可忽略)########## 
const int N=1e5+7,M=2e5+7,INF=0x3f3f3f3f,mod=1e8+7,P=131;
int n;
int a[N];
int d[N];
bool st[N];
void topo(){
    
    
	queue<int>q;
	for(int i=1;i<=n;i++){
    
    
		if(!d[i]){
    
    //如果度为0则删除,st为true表示删除
			st[i]=true;
			d[a[i]]--;//与他相连的点的度-1
			q.push(i);
		}
	}
	while(!q.empty()){
    
    
		int u=q.front();q.pop();
		int to=a[u];
		if(!d[to]){
    
    //一直去找到不是环里的点删除
			st[to]=true;
			d[a[to]]--;
			q.push(to);
		}
	}
} 
int main(){
    
    
	cin>>n;
	for(int i=1;i<=n;i++){
    
    
		cin>>a[i];
		d[a[i]]++;
	}
	topo();//拓扑思想删除不是环的点
	
	int maxv=0;
	for(int i=1;i<=n;i++){
    
    
		if(st[i])continue;//如果已经删除就跳过
		st[i]=true;//这个点是环的也删除
		int now=i,res=1;//now表示当前点,res表示环的大小
		while(a[now]!=i){
    
    //循环找环
			res++;
			st[i]=true;
			now=a[now];
		}
		maxv=max(maxv,res);
	}
	cout<<maxv<<endl;
	return 0;
}

猜你喜欢

转载自blog.csdn.net/weixin_43738764/article/details/109037057
今日推荐