题目:小朋友崇拜圈
分析:DSF
问题1:怎么判断是不是环边
答案1:凡是走过的打上标记
问题2:怎么求人数
答案2:环边的最后一条边的编号-环的第一条边的编号+1
问题3:找到环后需不需要继续移动
答案3:不用,一个小朋友只有一个崇拜的人
问题4:怎么避免重走其他节点走过的路
回答4:剪枝
#include <bits/stdc++.h>
using namespace std;
const int N = 1e5 + 10;
int n, nex[N], number[N], knowed[N], ans = 0;
void dfs(int x, int cnt, int id) {
knowed[x] = id; // 标记当前节点属于哪个圈
number[x] = cnt; // 记录当前节点的步数
if (knowed[nex[x]]) { // 如果下一个节点已经被访问过
if (knowed[nex[x]] == id) { // 如果下一个节点属于当前圈
ans = max(ans, cnt - number[nex[x]] + 1); // 更新最大圈的大小
}
return;
} else {
dfs(nex[x], cnt + 1, id); // 递归遍历下一个节点
}
}
int main() {
cin >> n;
for (int i = 1; i <= n; i++) {
cin >> nex[i];
}
memset(knowed, 0, sizeof(knowed)); // 初始化 knowed 数组
for (int i = 1; i <= n; i++) {
if (!knowed[i]) { // 如果当前节点未被访问过
dfs(i, 0, i); // 开始 DFS
}
}
cout << ans << endl;
return 0;
}