[并查集][NOIP2015]信息传递

信息传递

题目描述

有 N 个同学( 编号为 1 到 N) 正在玩一个信息传递的游戏。 在游戏里每人都有一个固定的信息传递对象, 其中,编号为i的同学的信息传递对象是编号为ti的同学。
游戏开始时, 每人都只知道自己的生日。之后每一轮中, 所有人会同时将自己当前所知的生日信息告诉各自的信息传递对象 ( 注意: 可能有人可以从若干人那里获取信息,但是每人只会把信息告诉一个人,即自己的信息传递对象)。 当有人从别人口中得知自己的生日时, 游戏结束。 请问该游戏一共可以进行几轮?

输入

输入文件名为 message.in。
输入共 2 行。
第 1 行包含 1 个正整数 N,表示 N个人。
第 2 行包含 N个用空格隔开的正整数 T1, T2, … … , Tn,其中第i个整数Ti表示编号为 i
的同学的信息传递对象是编号为 Ti 的同学, Ti ≤ n 且 Ti ≠ i
数据保证游戏一定会结束。

输出

输出文件名为 message.out。
输出共 1 行,包含 1 个整数,表示游戏一共可以进行多少轮。

样例输入

5
2 4 2 3 1

样例输出

3

提示

[并查集][NOIP2015]信息传递

用并查集找到最小环就好啦QAQQ

还是蛮简单的一道题qwqq

上代码吧~:

 #include<cstdio>
#include<iostream> int fa[], d[], n, minn, last; int read(){
int x = , f = ;
char ch = getchar();
while (ch < '' || ch > '') {
if (ch == '-') {
f = -;
}
ch = getchar();
}
while (ch >= '' && ch <= '') {
x = x * + ch - '';
ch = getchar();
}
return x * f;
} int find(int x){
if (fa[x] != x) {
int last = fa[x];
fa[x] = find(fa[x]);
d[x] += d[last];
}
return fa[x];
} void check(int a, int b){
int x = find(a), y = find(b);
if (x != y) {
fa[x] = y;
d[a] = d[b] + ;
}
else {
minn = std::min(minn, d[a] + d[b] + );
}
return;
} int main(){
int i, t;
n = read();
for (i = ; i <= n; i++) {
fa[i] = i;
}
minn = 0x7777777;
for (i = ; i <= n; i++) {
t = read();
check(i, t);
}
printf("%d",minn);
return ;
}
上一篇:(数据科学学习手札02)Python与R在循环语句与条件语句上的异同


下一篇:July 24th, Week 31st Sunday, 2016