资源限制
时间限制:1.0s 内存限制:256.0MB
班里N个小朋友,每个人都有自己最崇拜的一个小朋友(也可以是自己)。
在一个游戏中,需要小朋友坐一个圈,
每个小朋友都有自己最崇拜的小朋友在他的右手边。
求满足条件的圈最大多少人?
小朋友编号为1,2,3,...N
输入第一行,一个整数N(3<N<100000)
接下来一行N个整数,由空格分开。
要求输出一个整数,表示满足条件的最大圈的人数。
例如:
输入格式
9
3 4 2 5 3 8 4 6 9
则程序应该输出:
4
解释:
如图所示,崇拜关系用箭头表示,红色表示不在圈中。
显然,最大圈是[2 4 5 3] 构成的圈
再例如:
输入格式
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
程序应该输出:
16
资源约定:
峰值内存消耗(含虚拟机) < 256M
CPU消耗 < 1000ms
请严格按要求输出,不要画蛇添足地打印类似:“请您输入...” 的多余内容。
所有代码放在同一个源文件中,调试通过后,拷贝提交该源码。
不要使用package语句。不要使用jdk1.7及以上版本的特性。
主类的名字必须是:Main,否则按无效代码处理。
Code
#define _CRT_SECURE_NO_WARNINGS
#include<bits/stdc++.h>
using namespace std;
const int N= 1e5 + 1;
int n;
int like[N];
int cnt, maxx;
int vis[N];
inline int read() {//快读
char ch = getchar(); int x = 0;
while (ch < '0' || ch>'9')
ch = getchar();
while (ch >= '0' && ch <= '9') {
x = x * 10 + ch - '0';
ch = getchar();
}return x;
}
void dfs(int i, int j) {//初始时i=j。搜索完后,i为环展开的最左侧 j为最右侧的崇拜的小孩的编号,应该为i
if (vis[i] && i != j) //如果i号小孩已经搜索过且没成环
return;
if (vis[i] && i == j) {//i号已经搜索过且形成了回环
maxx = max(cnt, maxx);//更新最大值
return;
}
cnt++;
vis[i] = 1;
dfs(like[i], j);//继续搜索i崇拜的,一直到like[i]=j
vis[i] = 0;//回溯
}
int main() {
n = read();
for (int i = 1; i <= n; i++)
like[i] = read();
for (int i = 1; i <= n; i++) {
cnt = 0;
dfs(i, i);//每个小孩都作为最左侧搜索一遍
}
printf("%d", maxx);
return 0;
}