思路:拓扑排序可以判环 那么也可以把非环的边去掉
这样我们只要成环的所有边 这样我们的图就剩下了很多环
这样每个环只搜一次然后记录最大值即可。
虽然思路写起来简单但是很难想啊!!!
#include<algorithm>
#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<cmath>
#include<queue>
#define ll long long
#define inf 0x3f3f3f3f
#define sd(a) scanf("%d",&a)
#define sdd(a,b) scanf("%d%d",&a,&b)
#define cl(a,b) memset(a,b,sizeof(a))
#define rep(i,a,n) for(int i=a;i<=n;i++)
#define sddd(a,b,c) scanf("%d%d%d",&a,&b,&c)
#define dbg() printf("aaa\n")
using namespace std;
const int maxn=1e5+10;
int n;
int a[maxn];
int in[maxn];
bool con[maxn];
queue<int> q;
int main() {
sd(n);
rep(i,1,n){
sd(a[i]);
in[a[i]]++;
con[i]=0;
}
rep(i,1,n){
if(in[i]==0) q.push(i);
}
while(!q.empty()){
int i=q.front();
q.pop();
in[a[i]]--;
if(in[a[i]]==0){
q.push(a[i]);
}
}//至此已经去掉所有环之外的点
int maxx=0;
rep(i,1,n){
if(in[i]==0) continue;
if(con[i]==true) continue;
con[i]=true;
int num=1;
int t=a[i];
while(t!=i){//这里好好想想
con[t]=true;
t=a[t];
num++;
}
if(maxx<num) maxx=num;
}
printf("%d\n",maxx);
return 0;
}
题目描述
班里N个小朋友,每个人都有自己最崇拜的一个小朋友(也可以是自己)。
在一个游戏中,需要小朋友坐一个圈,
每个小朋友都有自己最崇拜的小朋友在他的右手边。
求满足条件的圈最大多少人?
小朋友编号为1,2,3,…N
输入
输入第一行,一个整数N(3<N<100000)
接下来一行N个整数,由空格分开。
输出
要求输出一个整数,表示满足条件的最大圈的人数。
样例输入
9
3 4 2 5 3 8 4 6 9
样例输出
4