【题解:洛谷2661 信息传递】

传送门:(https://www.luogu.org/problemnew/show/P2661)
题目描述

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

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

输入输出格式

输入格式:
共2行。

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

第2行包含 n 个用空格隔开的正整数 T_1,T_2,⋯⋯T_n。其中第 i 个整数 T_i
​表示编号为 i的同学的信息传递对象是编号为 T_i 的同学,
输出格式:
11个整数,表示游戏一共可以进行多少轮。
输入样例1:
5
2 4 2 3 1
输出样例1:
3
说明

样例解释

游戏的流程如图所示。当进行完第 3轮游戏后, 4号玩家会听到 2 号玩家告诉他自己的生日,所以答案为 3。当然,第 3 轮游戏后, 2号玩家、3 号玩家都能从自己的消息来源得知自己的生日,同样符合游戏结束的条件。

对于 30%的数据, n ≤ 200;
对于 60%的数据, n ≤ 2500;
对于 100%的数据, n ≤ 200000。

分析

题非常简单,就是要求一个有向图中的最小环的边权总和。
由于图中每一条边权值都为1,而这个有向图里每一个人都只有1个信息传递的对象,也就是说每个点的出度都为1。由这一点不难发现这个环里点的数量等于边的数量。
值得一提的是,在这个有向图中,环必然是一个强连通分量,可以tarjan出来。
所以算法如下:
1.建图。
2.tarjan,注意原图可能由多个连通块组成,所以要跑一边全图。
3.找最小环中有多少节点。
代码:

#include<bits/stdc++.h>
using namespace std;
inline int read(){
	char ch;
	while((ch=getchar())<'0'||ch>'9') ;
	int ans=ch-48;
	while((ch=getchar())>='0'&&ch<='9') ans=ans*10+ch-48;
	return ans;
}
inline void write(int x){
	if(x<0) putchar('-') ,x=-x;
	if(x>9)	write(x/10);
	putchar(x%10+'0');
}
int n;
int head[200001],low[200001],dfn[200001],size[200001];
int scc[200001],vis[200001];
int cnt=0,num=0,color=0;
struct node{
	int u,v,nt;
}e[200001];
inline void add(int u,int v){
	cnt++;
	e[cnt]=(node){u,v,head[u]};
	head[u]=cnt;
}
stack<int>st;
inline void tarjan(int x){
	low[x]=dfn[x]=++num;
	st.push(x),vis[x]=1;
	for(int i=head[x];i;i=e[i].nt){
		int v=e[i].v;
		if(!dfn[v]){
			tarjan(v);
			low[x]=min(low[x],low[v]);
		}
		else if(vis[v]) low[x]=min(low[x],dfn[v]);
	}
	if(low[x]==dfn[x]){
		color++;
		while(1){
			int t=st.top();st.pop();
			vis[t]=0;scc[t]=color;
			size[color]++;
			if(t==x) break;
		}
		
	}
}
int main(){
	n=read();
	int v;
	for(int i=1;i<=n;i++){
		v=read();
		add(i,v);
	}
	for(int i=1;i<=n;i++) if(!dfn[i]) tarjan(i);
	sort(size+1,size+color+1);
	for(int i=1;i<=color;i++){
		if(size[i]>1) {
			write(size[i]);
			break;
		}
	}
	return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_43263852/article/details/86141174
今日推荐