import java.util.*;
import java.io.*;
public class Main {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
int n = in.nextInt();
int[] p = new int[n];
for (int i = 0; i < n; i++) {
p[i] = in.nextInt() - 1;
}
int[] indeg = new int[n];
for (int i = 0; i < n; i++) {
indeg[p[i]]++;
}
Queue<Integer> queue = new LinkedList<>();
for (int i = 0; i < n; i++) {
if (indeg[i] == 0) {
queue.offer(i);
}
}
List<Integer> topoOrder = new ArrayList<>();
while (!queue.isEmpty()) {
int u = queue.poll();
topoOrder.add(u);
int v = p[u];
indeg[v]--;
if (indeg[v] == 0) {
queue.offer(v);
}
}
int[] ans = new int[n];
for (int i = 0; i < n; i++) {
if (indeg[i] > 0) {
ans[i] = i;
}
}
// p[u]是拓扑排序靠后的 一定被计算过
for (int i = topoOrder.size() - 1; i >= 0; i--) {
int u = topoOrder.get(i);
ans[u] = ans[p[u]];
}
StringBuilder sb = new StringBuilder();
for (int i = 0; i < n; i++) {
sb.append(ans[i] + 1).append(" ");
}
System.out.println(sb.toString().trim());
}
}
就是找到每个点到环的入口。
巧妙使用拓扑排序进行DP。

京公网安备 11010502036488号