题目信息
题目传送门
解题思路
- 把每个人看成一个点,信息传递就是边,轮数就是最小环。
- A传递给B信息,就从A连一条指向B的边,同时更新A的父节点。
- A到父节点的路径长度 = B到父节点的路径长度 + 1
- 如果两个点A和B的祖先相同,可构成环。
- 长度 = A到父节点的路径长度 + B到父节点的路径长度 + 1
代码实现
#include <bits/stdc++.h>
using namespace std;
const int N = 200005;
int fa[N], sizes[N];
int n, minn = INT_MAX;
int get(int u) {
if (fa[u] != u) {
int v = fa[u];
fa[u] = get(fa[u]);
sizes[u] += sizes[v];
}
return fa[u];
}
void merge(int u, int v) {
int _u = get(u), _v = get(v);
if (_u != _v) {
fa[_u] = _v;
sizes[u] = sizes[v] + 1;
} else {
minn = min(minn, sizes[u] + sizes[v] + 1);
}
}
int main() {
cin >> n;
for (int i = 1; i <= n; ++i) {
fa[i] = i;
}
for (int u = 1; u <= n; ++u) {
int v;
cin >> v;
merge(u, v);
}
cout << minn << '\n';
return 0;
}