试题描述:

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

输入:

共2行,第1行包含1个正整数 n ,表示 n 个人。
第2行包含 n 个用空格隔开的正整数T_1,T_2,...,T_n ,其中第 i 个整数 T_i 表示编号为 i 的同学的信息传递对象是编号为 T_i 的同学, T_i <= n 且 T_i 不等于 i 。
数据保证游戏一定会结束。

输出:

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

输入示例:

5
2 4 2 3 1

输出示例:

3

数据范围:

n<=200000

--------------------------------------------分隔线--------------------------------------------------------

这题看了题就知道其实我们所要干的一件事就是找最小环……(其实我考试的时候也知道是要最小环,可不知道怎么找啊……于是乎写了一个根本错的东西但不知道怎么回事还蒙了30分……学了一年C++,就差这么一道题的70,我的省一啊……)

上面的废话选择性忽略好了……下面来说这道题的重点……

找最小环的话果断要用到强连通分量。

强连通分量:对于一个有向图的顶点的子集S,如果在S内任取两个顶点u和v,都能找到一条从u到v的路径,那么就称S是强连通的。如果在强连通的顶点集合S中加入其他任意顶点集合后,它都不再是强连通的,那么就称S是原图的一个强连通分量(SCC :Strongly Connected Component)

强连通分量的分解可以用两次简单的dfs来实现。

第一次dfs的时候,选取任意顶点作为起点,遍历所有未访问过的顶点,在回溯前给定点标号。对剩余未访问过的顶点不断重复上述过程。

完成标号后越接近图的尾部,定点的标号越小。

第二次dfs时先将所有的边反向,然后以标号最大的顶点为起点进行dfs,这样可以把图的拓扑序储存。

代码如下:

 #include<iostream>
#include<cctype>
using namespace std;
const int MAXN=+;
void read(int &x){
x=;int f=;char ch=getchar();
for(;!isdigit(ch);ch=getchar())if(ch=='-')f=-;
for(;isdigit(ch);ch=getchar())x=x*+ch-'';
x*=f;
}
//----------------------
int v[MAXN],first[MAXN],next[MAXN],e;
void AddEdge(int a,int b){
v[++e]=b;
next[e]=first[a];
first[a]=e;
} int vr[MAXN],firstr[MAXN],nextr[MAXN],er;
void AddEdger(int a,int b){
vr[++er]=b;
nextr[er]=firstr[a];
firstr[a]=er;
}
//----------------------
int n,tot,vs[MAXN],topo[MAXN];
bool vis[MAXN];
void dfs(int x){
vis[x]=;
for(int i=first[x];i;i=next[i])
if(!vis[v[i]])dfs(v[i]);
vs[++tot]=x;
} void dfsr(int x,int k){
vis[x]=;
topo[x]=k;
for(int i=firstr[x];i;i=nextr[i])
if(!vis[vr[i]])dfsr(vr[i],k);
}
//---------------------------
int cnt[MAXN];
int main(){
read(n);
for(int i=;i<=n;i++){
int tmp;
read(tmp);
AddEdge(i,tmp);
AddEdger(tmp,i);
} memset(vis,,sizeof(vis));
for(int i=;i<=n;i++)
if(!vis[i])dfs(i); int k=;
memset(vis,,sizeof(vis));
for(int i=n;i>=;i--)
if(!vis[vs[i]])dfsr(vs[i],k++); for(int i=;i<=n;i++)cnt[topo[i]]++;
int ans=-1u>>;
for(int i=;i<=topo[vs[]];i++){
if(cnt[i]!=)ans=min(ans,cnt[i]);
}
printf("%d\n",ans);
}

noip201506 Message 信息传递的更多相关文章

  1. 使用postMesssage()实现跨域iframe页面间的信息传递----转载

    由于web同源策略的限制,当页面使用跨域iframe链接时,主页面与子页面是无法交互的,这对页面间的信息传递造成了不小的麻烦,经过一系列的尝试,最后我发现有以下方法可以实现: 1. 子页面url传参 ...

  2. 如何在Azure环境里做好信息传递可扩展性经验分享

    作者 王枫 发布于2014年5月15日 综述 本文介绍建立一个在Azure上使用Azure服务总线, 高吞吐量短信平台的必要步骤.在这篇文章中提出的解决方案是在响应由客户的具体要求,建立一个基于Win ...

  3. 【NOIP2015提高组】 Day1 T2 信息传递

    题目描述 有n个同学(编号为1到n)正在玩一个信息传递的游戏.在游戏里每人都有一个固定的信息传递对象,其中,编号为i的同学的信息传递对象是编号为Ti同学. 游戏开始时,每人都只知道自己的生日.之后每一 ...

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

    信息传递 题目描述 有 N 个同学( 编号为 1 到 N) 正在玩一个信息传递的游戏. 在游戏里每人都有一个固定的信息传递对象, 其中,编号为i的同学的信息传递对象是编号为ti的同学. 游戏开始时, ...

  5. tg2015 信息传递 (洛谷p2661)

    题目描述 有n个同学(编号为1到n)正在玩一个信息传递的游戏.在游戏里每人都有一个固定的信息传递对象,其中,编号为i的同学的信息传递对象是编号为Ti同学. 游戏开始时,每人都只知道自己的生日.之后每一 ...

  6. [NOIP2015]信息传递

    [NOIP2015]信息传递[问题描述]有

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

    题目描述 有n个同学(编号为1到n)正在玩一个信息传递的游戏.在游戏里每人都有一个固定的信息传递对象,其中,编号为i的同学的信息传递对象是编号为Ti同学. 游戏开始时,每人都只知道自己的生日.之后每一 ...

  8. 洛谷 P2661 信息传递 Label:并查集||强联通分量

    题目描述 有n个同学(编号为1到n)正在玩一个信息传递的游戏.在游戏里每人都有一个固定的信息传递对象,其中,编号为i的同学的信息传递对象是编号为Ti同学. 游戏开始时,每人都只知道自己的生日.之后每一 ...

  9. NOIP 2015 信息传递

    kawayi 题目描述 有n个同学(编号为1到n)正在玩一个信息传递的游戏.在游戏里每人都有一个固定的信息传递对象,其中,编号为i的同学的信息传递对象是编号为Ti同学. 游戏开始时,每人都只知道自己的 ...

随机推荐

  1. UITextFiled自动补全输入,选中补全内容。NSRange和UITextRange的相互转换。-b

    有个需求就是 需要用户输入几位以后账号,可以根据本地存储的登录成功的账号,进行自动补全,并且补全内容为选中状态,不影响用户的新输入. 研究了一下,下面是完整的实现的方法. 补充个下载地址http:// ...

  2. 浅谈Java内存泄露

    一.引言 先等等吧……累了

  3. 玩了一下SDN:MININET+FLOODLIGHT,感觉这确实是一个趋势啊

    功能用增加中间层的方案来解决. 仿佛回到用交换机和路由器模拟器的感觉. 遇到执行命令小问题,狗哥搞定: mininet>mininet> dpctl dump-flows tcp:127. ...

  4. Xamarin.Forms Hello word

    创建项目 XMD1右键->添加->新建项目 MDPage:MasterDetailPage 主窗体,导航与明细的布局窗体. 指定MenuPage.xaml 作为Master <?xm ...

  5. 【HDOJ】1063 Exponentiation

    这道题目莫名其妙的wa,又莫名其妙的过了. import java.util.Scanner; import java.math.BigDecimal; public class Main { pub ...

  6. 【转】(DT系列五)Linux kernel 是怎么将 devicetree中的内容生成plateform_device

    原文网址:http://www.cnblogs.com/biglucky/p/4057495.html Linux kernel 是怎么将 devicetree中的内容生成plateform_devi ...

  7. Delphi 多线程的操作

    Delphi 操作多线程的代码, 在项目中需要在webservice中使用多线程,程序思想如下: 1.就创建一个线程, 也就是说有两个线程,主线程和创建的线程, 主线程用于程序的别的操作,例如停止服务 ...

  8. Android 各版本信息 (维基百科)

    The following tables show the release dates and key features of all Android operating system updates ...

  9. Sqlserver2012 alwayson部署攻略

    http://wenku.baidu.com/link?url=3Gl5nwxE6Rq4ZKGaKWpYZ1D4OdwVLcVeMoGTOmFSILDJzanPy9fwMPRwr7CRu4HhDzXr ...

  10. bitree

    #include "stdio.h" #include "stdlib.h" #define OVERFLOW -1 #define ERROR -1 #def ...