[NOIP2015]信息传递

[NOIP2015]信息传递
【问题描述】
有??个同学(编号为1到??)正在玩一个信息传递的游戏。在游戏里每人都有一个固定的信息传递对象,其中,编号为?? 的同学的信息传递对象是编号为????的同学。游戏开始时,每人都只知道自己的生日。之后每一轮中,所有人会同时将自己当前所知的生日信息告诉各自的信息传递对象(注意:可能有人可以从若干人那里获取信息,但是每人只会把信息告诉一个人,即自己的信息传递对象)。当有人从别人口中得知自己的生日时,游戏结束。请问该游戏一共可以进行几轮?
【输入格式】
输入文件名为message.in。
输入共2行。
第1行包含1个正整数??,表示??个人。
第2行包含?? 个用空格隔开的正整数??1,??2,……,????,其中第?? 个整数????表示编号为??的同学的信息传递对象是编号为Ti的同学,????≤?? 且????≠??。
数据保证游戏一定会结束。
【输出格式】
输出文件名为message.out。
输出共1行,包含1个整数,表示游戏一共可以进行多少轮。
【输入输出样例】
message.in
5
2 4 2 3 1
message.out
3
游戏的流程如图所示。当进行完第3轮游戏后,4号玩家会听到2号玩家告诉他自己的生日,所以答案为3。当然,第3轮游戏后,2号玩家、3号玩家都能从自己的消息来源得知自己的生日,同样符合游戏结束的条件。
【数据规模与约定】
对于30%的数据,??≤200;
对于60%的数据,??≤2500;
对于100%的数据,??≤200000。

这天洛谷莫名其妙地登不上去了,在vijos上边交的AC了。

这个东西可以给他变成一个有向图,其中每一个。。。节点的出度为1,每一个节点的入度的和是n。。。

比如说下图中的这个(请暂时忽略掉有颜色的东西;)

然后是思路:

很容易想到我们要找到最小环的长度,因为在最小环上传递的信息能够最先看到(自己想一想就能明白了)。

为了求最小环方便,我们首先就是去掉入度为0的点,因为这些点不会接受到任何消息(也不会在环中出现),怎么去掉呢?用一个数组记录它的入度就行了。

与此同时,如果我们去掉了一个入度为0的点导致另一个点的入度变为0,那么把另一个点也去掉,依次类推。

这样子就剩下了一个只剩环的图了。我们用一个d数组来记录就行了。

#include <cstdio>
#include <iostream>
#include <cstring>
using namespace std;
int n,to[200001],fromcnt[200001]={0},d[200001],ans=999999;
bool dev[200001];
void ts()//调试
{
	printf("************\n");
	printf("%d\n",n);
	for(int i=1;i<=n;i++)
		printf("%5d",to[i]);
	printf("\n");
	for(int i=1;i<=n;i++)
		printf("%5d",fromcnt[i]);
	printf("\n");
	for(int i=1;i<=n;i++)
		printf("%5d",d[i]);
	printf("\n");
	for(int i=1;i<=n;i++)
		printf("%5d",dev[i]);
	printf("\n");
	printf("************\n");
}
void NaOH(int x)//利用NaOH的强腐蚀性腐蚀掉不在环中的点
{
	dev[x]=true;//dev[x]就表示x节点是否被删除
	fromcnt[to[x]]--;//让x指向的节点的入度-1
	if(fromcnt[to[x]]==0)//如果入度为0
		NaOH(to[x]);//利用NaOH的强腐蚀性把指向的那个点腐蚀掉
}
int dfs(int x,int src,int deep)//深度优先搜索
{
	if(dev[x])return 0;
//	printf("%d %d %d\n",x,src,deep);
	if(src==x)
	{
		ans=min(ans,deep);
		return deep;
	}
	else return d[x]=dfs(to[x],src,deep+1);
}
int main()
{
	memset(fromcnt,0,sizeof(fromcnt));
	memset(d,0xff,sizeof(d));
	scanf("%d",&n);
	for(int i=1;i<=n;i++)
	{
		scanf("%d",&to[i]);
		fromcnt[to[i]]+=1;
	}
	for(int i=1;i<=n;i++)
		if(fromcnt[i]==0)
			NaOH(i);
	for(int i=1;i<=n;i++)
		if(dev[i]==0&&d[i]==-1)
			dfs(to[i],i,1);
	printf("%d\n",ans);
	return 0;
}

2

2

时间: 2024-08-05 14:10:04

[NOIP2015]信息传递的相关文章

noip2015 信息传递 强连通块

时隔好久,重新把那些题找出来,写一写了,毕竟实力还很有限,得学. 一开始,最大的疑惑还是怕一个环里有另外一个环(毕竟经验不丰富),后来看到了这段话 T2 信息传递 大意:在一个只有n条有向边的图中,每个结点出度为1,求一个包含节点数最少的环. 分析:因为只有n条边并且每个点都有且仅有一条边连出去,所以只可能存在简单环,不会出现那种8字形的环套环. 证明:每个点有两种情况:1.不在任何一个环中 这样的点可以直接忽略掉,看成是有n-1个点,n-1条边来证明就行了.2.在某个环中.那么如果我们现在有了

2105. [NOIP2015] 信息传递

★☆   输入文件:2015message.in   输出文件:2015message.out   简单对比 时间限制:1 s   内存限制:256 MB [题目描述] 有n个同学(编号为1到n)正在玩一个信息传递的游戏.在游戏里每人都有一个固定的信息传递对象,其中,编号为i的同学的信息传递对象是编号为Ti同学. 游戏开始时,每人都只知道自己的生日.之后每一轮中,所有人会同时将自己当前所知的生日信息告诉各自的信息传递对象(注意:可能有人可以从若干人那里获取信息,但是每人只会把信息告诉一个人,即自

图论例题1——NOIP2015信息传递

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

cogs luogu 2105. [NOIP2015] 信息传递

★☆   输入文件:2015message.in   输出文件:2015message.out   简单对比 时间限制:1 s   内存限制:256 MB [题目描述] 有n个同学(编号为1到n)正在玩一个信息传递的游戏.在游戏里每人都有一个固定的信息传递对象,其中,编号为i的同学的信息传递对象是编号为Ti同学. 游戏开始时,每人都只知道自己的生日.之后每一轮中,所有人会同时将自己当前所知的生日信息告诉各自的信息传递对象(注意:可能有人可以从若干人那里获取信息,但是每人只会把信息告诉一个人,即自

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

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

【NOIP2015】信息传递

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

信息传递 NOIP2015 day1 T2

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

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

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

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

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