NOIP2015提高组T2 洛谷P2661 信息传递

题目描述

有n个同学(编号为1到n)正在玩一个信息传递的游戏。在游戏里每人都有一个固定的信息传递对象,其中,编号为i的同学的信息传递对象是编号为Ti同学。

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

输入输出格式

输入格式:

输入共2行。

第1行包含1个正整数n表示n个人。

第2行包含n个用空格隔开的正整数T1,T2,……,Tn其中第i个整数Ti示编号为i

的同学的信息传递对象是编号为Ti的同学,Ti≤n且Ti≠i

数据保证游戏一定会结束。

输出格式:

输出共 1 行,包含 1 个整数,表示游戏一共可以进行多少轮。

输入输出样例

输入样例#1:

5
2 4 2 3 1

输出样例#1:

3

说明

样例1解释

游戏的流程如图所示。当进行完第 3 轮游戏后, 4 号玩家会听到 2 号玩家告诉他自

己的生日,所以答案为 3。当然,第 3 轮游戏后, 2 号玩家、 3 号玩家都能从自己的消息

来源得知自己的生日,同样符合游戏结束的条件。

对于 30%的数据, n ≤ 200;

对于 60%的数据, n ≤ 2500;

对于 100%的数据, n ≤ 200000。

跑一边tarjan缩点,找出包含点数最少(但不等于1)的缩点,其包含点数就是答案。

因为每个点出度最多为1,所以不需要用复杂的方式存边,只开个数组记录每个点的去向就行。

 1 /**/
 2 #include<iostream>
 3 #include<cstdio>
 4 #include<cmath>
 5 #include<cstring>
 6 #include<algorithm>
 7 using namespace std;
 8 const int mxn=230000;
 9 int v[mxn];
10 int dtime=0;
11 bool inst[mxn];
12 int st[mxn],top;
13 int low[mxn],dfn[mxn];
14 //
15 int belone[mxn],cnt=0;
16 int dg[mxn];
17 //
18 int n;
19 void tarjan(int u){
20     low[u]=dfn[u]=++dtime;
21     st[++top]=u;
22     inst[u]=1;
23     //
24     if(!dfn[v[u]]){
25         tarjan(v[u]);
26         low[u]=min(low[u],low[v[u]]);
27     }
28     else if(inst[v[u]])
29         low[u]=min(low[u],dfn[v[u]]);
30     //
31     if(low[u]==dfn[u]){
32         ++cnt;
33         int w;
34         do{
35             w=st[top--];
36             dg[cnt]++;
37             inst[w]=0;
38         }while(w!=u);
39     }
40     return;
41 }
42 int main(){
43     scanf("%d",&n);
44     int i,j;
45     for(i=1;i<=n;i++){
46         scanf("%d",&v[i]);
47     }
48     for(i=1;i<=n;i++){
49         if(!dfn[i])tarjan(i);
50     }
51     int ans=5000000;
52     for(i=1;i<=cnt;i++) {if(dg[i]<ans && dg[i]!=1)ans=dg[i];}
53     printf("%d\n",ans);
54     return 0;
55 }
时间: 2024-10-01 23:46:27

NOIP2015提高组T2 洛谷P2661 信息传递的相关文章

洛谷P2661 信息传递 类似tarjan 强连通 灌水

洛谷P2661 信息传递类似tarjan 强连通 灌水 题意 求一个特殊的图的最小环 这个图 有一个性质 每个点只有一条出边 这样满足一个性质,一张图只有 一个环,以及别的连向他们的边都是一些连向 或者 间接连向这个环的树枝 这些树枝一定不会连成环,因为 每个点只有一条出边,而不可能有两条,所以只要把这些树枝边都删掉,然后再类似tarjan一样跑一遍灌水就行了 先说一下思路,这整道题就是给你几个带枝叶的环要你求最短环而已,于是在输入的时候可以把图中每个点的入度记录下来,然后再删除那些入度为0的点

洛谷P2661 信息传递==coedevs4511 信息传递 NOIP2015 day1 T2

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

[NOIP2015] 提高组 洛谷P2661 信息传递

题目描述 有n个同学(编号为1到n)正在玩一个信息传递的游戏.在游戏里每人都有一个固定的信息传递对象,其中,编号为i的同学的信息传递对象是编号为Ti同学. 游戏开始时,每人都只知道自己的生日.之后每一轮中,所有人会同时将自己当前所知的生日信息告诉各自的信息传递对象(注意:可能有人可以从若干人那里获取信息,但是每人只会把信息告诉一个人,即自己的信息传递对象).当有人从别人口中得知自己的生日时,游戏结束.请问该游戏一共可以进行几轮? 输入输出格式 输入格式: 输入共2行. 第1行包含1个正整数n表示

洛谷——P2661 信息传递

https://www.luogu.org/problem/show?pid=2661#sub 题目描述 有n个同学(编号为1到n)正在玩一个信息传递的游戏.在游戏里每人都有一个固定的信息传递对象,其中,编号为i的同学的信息传递对象是编号为Ti同学. 游戏开始时,每人都只知道自己的生日.之后每一轮中,所有人会同时将自己当前所知的生日信息告诉各自的信息传递对象(注意:可能有人可以从若干人那里获取信息,但是每人只会把信息告诉一个人,即自己的信息传递对象).当有人从别人口中得知自己的生日时,游戏结束.

洛谷 P2661信息传递

题目描述 有n个同学(编号为1到n)正在玩一个信息传递的游戏.在游戏里每人都有一个固定的信息传递对象,其中,编号为i的同学的信息传递对象是编号为Ti同学. 游戏开始时,每人都只知道自己的生日.之后每一轮中,所有人会同时将自己当前所知的生日信息告诉各自的信息传递对象(注意:可能有人可以从若干人那里获取信息,但是每人只会把信息告诉一个人,即自己的信息传递对象).当有人从别人口中得知自己的生日时,游戏结束.请问该游戏一共可以进行几轮? 输入输出格式 输入格式: 输入共2行. 第1行包含1个正整数n表示

洛谷 P2661 信息传递 Label:并查集?

题目描述 有n个同学(编号为1到n)正在玩一个信息传递的游戏.在游戏里每人都有一个固定的信息传递对象,其中,编号为i的同学的信息传递对象是编号为Ti同学. 游戏开始时,每人都只知道自己的生日.之后每一轮中,所有人会同时将自己当前所知的生日信息告诉各自的信息传递对象(注意:可能有人可以从若干人那里获取信息,但是每人只会把信息告诉一个人,即自己的信息传递对象).当有人从别人口中得知自己的生日时,游戏结束.请问该游戏一共可以进行几轮? 输入输出格式 输入格式: 输入共2行. 第1行包含1个正整数n表示

洛谷 P2661 信息传递

这题好久前就做过了...结果过了几个月还是不会...题解也看不懂...不过参考题解的一部分倒是懂了. 首先把每个人当做一个节点,从每个人向他要告诉的那个人连边,产生一张有向图.显然,一个人如果不在环上,那么就永远不可能听到自己的信息:一个人如果在环上,那么就会在进行“包含这个点的长度最小的环的长度"轮之后听到自己的信息.现在要求所有人听到自己信息的轮数的最小值,也就是要求图的最小环. 裸的最小环应该是floyed,$O(n^3)$.显然是不行的.可以注意到一点,就是这题的图中每个点最多只有一条出

[NOIP2015] 提高组 洛谷P2615 神奇的幻方

题目描述 幻方是一种很神奇的N*N矩阵:它由数字1,2,3,……,N*N构成,且每行.每列及两条对角线上的数字之和都相同. 当N为奇数时,我们可以通过以下方法构建一个幻方: 首先将1写在第一行的中间. 之后,按如下方式从小到大依次填写每个数K(K=2,3,…,N*N): 1.若(K−1)在第一行但不在最后一列,则将K填在最后一行,(K−1)所在列的右一列: 2.若(K−1)在最后一列但不在第一行,则将K填在第一列,(K−1)所在行的上一行: 3.若(K−1)在第一行最后一列,则将K填在(K−1)

洛谷-神奇的幻方-NOIP2015提高组复赛

题目描述 幻方是一种很神奇的N*N矩阵:它由数字1,2,3,……,N*N构成,且每行.每列及两条对角线上的数字之和都相同. 当N为奇数时,我们可以通过以下方法构建一个幻方: 首先将1写在第一行的中间. 之后,按如下方式从小到大依次填写每个数K(K=2,3,…,N*N): 1.若(K−1)在第一行但不在最后一列,则将K填在最后一行,(K−1)所在列的右一列: 2.若(K−1)在最后一列但不在第一行,则将K填在第一列,(K−1)所在行的上一行: 3.若(K−1)在第一行最后一列,则将K填在(K−1)