问题描述
班里
N
N
N 个小朋友,每个人都有自己最崇拜的一个小朋友(也可以是自己)。
在一个游戏中,需要小朋友坐一个圈,每个小朋友都有自己最崇拜的小朋友在他的右手边。
求满足条件的圈最大多少人?小朋友编号为 1 , 2 , 3 , . . . N 1,2,3,...N 1,2,3,...N
输入格式
第一行,一个整数
N
N
N(
3
<
N
<
1
0
5
3 < N < 10^5
3<N<105)
第二行
N
N
N 个整数,由空格分开。
输出格式
要求输出一个整数,表示满足条件的最大圈的人数。
样例输入1
9
3 4 2 5 3 8 4 6 9
样例输出1
4
解释
如图所示,崇拜关系用箭头表示,红色表示不在圈中。
显然,最大圈是 [ 2 , 4 , 5 , 3 ] [2,4,5,3] [2,4,5,3] 构成的圈
样例输入2
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
样例输出2
16
题解:拓扑排序
解题思路
:先用拓扑排序去掉所有不成环的点,那么剩下的点都能找到对应的环,最后遍历所有环,取最大值即可。
#include <bits/stdc++.h>
using namespace std;
const int N = 100010;
int n, ans;
int d[N], admire[N];
bool used[N], check[N];
void dfs(int u, int len)
{
if(used[u])
{
ans = max(ans, len);
return;
}
used[u] = true;
dfs(admire[u], len + 1);
}
void topsort()
{
queue<int> q;
memset(check, true, sizeof check);
for (int i = 1; i <= n; i ++)
if(d[i] == 0)
{
q.push(i);
check[i] = false;
}
while(q.size())
{
int a = q.front(); q.pop();
int b = admire[a];
if(--d[b] == 0)
{
q.push(b);
check[b] = false;
}
}
}
int main()
{
cin >> n;
for (int i = 1; i <= n; i ++)
{
scanf("%d", &admire[i]);
d[admire[i]] ++;
}
topsort();
for (int i = 1; i <= n; i ++)
if(check[i] && !used[i])
dfs(i, 0);
cout << ans << endl;
return 0;
}