1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65
|
# include <iostream>
# include <cstdio>
# include <cstring>
# include <algorithm>
# include <cmath>
using namespace std;
const int N = 1000050;
int to[N], siz[N], n, vis[N], ins[N], sta[N];
int dfs(int x){
if(siz[x]) return siz[x];
return siz[x] = 1 + dfs(to[x]);
}
///ins是找环用的vis 每次要记得清空ins 否则下次还会找到同一个环 ///如果是某条直线多个点通向同一个环那么直线的点会多次访问ins避免重复计算相同的环 ///sta[0] 记录路径长度 sta[j]表示该路径第几个点在原图中的下标 int main() { int i, j, k, h; scanf("%d", &n); for(i = 1; i <= n; i ++) scanf("%d", &to[i]); for(i = 1; i <= n; i ++){ if(vis[i] == 0){ j = i; while(vis[j] == 0){ sta[++ sta[0]] = j; vis[j] = ins[j] = 1; j = to[j]; } if(ins[j]){ k = j, h = 0; do{ k = to[k]; h ++; }while(k != j); do{ k = to[k]; siz[k] = h; }while(k != j); } while(sta[0]){ ins[sta[sta[0]]] = 0; sta[0] --; } } } for(i = 1, h = 0; i <= n; i ++) h = max(h, dfs(i)); printf("%d", h); return 0; }
|