noip201506 Message 信息传递
试题描述:
有 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 信息传递的更多相关文章
- 使用postMesssage()实现跨域iframe页面间的信息传递----转载
由于web同源策略的限制,当页面使用跨域iframe链接时,主页面与子页面是无法交互的,这对页面间的信息传递造成了不小的麻烦,经过一系列的尝试,最后我发现有以下方法可以实现: 1. 子页面url传参 ...
- 如何在Azure环境里做好信息传递可扩展性经验分享
作者 王枫 发布于2014年5月15日 综述 本文介绍建立一个在Azure上使用Azure服务总线, 高吞吐量短信平台的必要步骤.在这篇文章中提出的解决方案是在响应由客户的具体要求,建立一个基于Win ...
- 【NOIP2015提高组】 Day1 T2 信息传递
题目描述 有n个同学(编号为1到n)正在玩一个信息传递的游戏.在游戏里每人都有一个固定的信息传递对象,其中,编号为i的同学的信息传递对象是编号为Ti同学. 游戏开始时,每人都只知道自己的生日.之后每一 ...
- [并查集][NOIP2015]信息传递
信息传递 题目描述 有 N 个同学( 编号为 1 到 N) 正在玩一个信息传递的游戏. 在游戏里每人都有一个固定的信息传递对象, 其中,编号为i的同学的信息传递对象是编号为ti的同学. 游戏开始时, ...
- tg2015 信息传递 (洛谷p2661)
题目描述 有n个同学(编号为1到n)正在玩一个信息传递的游戏.在游戏里每人都有一个固定的信息传递对象,其中,编号为i的同学的信息传递对象是编号为Ti同学. 游戏开始时,每人都只知道自己的生日.之后每一 ...
- [NOIP2015]信息传递
[NOIP2015]信息传递[问题描述]有
- [NOIP2015] 提高组 洛谷P2661 信息传递
题目描述 有n个同学(编号为1到n)正在玩一个信息传递的游戏.在游戏里每人都有一个固定的信息传递对象,其中,编号为i的同学的信息传递对象是编号为Ti同学. 游戏开始时,每人都只知道自己的生日.之后每一 ...
- 洛谷 P2661 信息传递 Label:并查集||强联通分量
题目描述 有n个同学(编号为1到n)正在玩一个信息传递的游戏.在游戏里每人都有一个固定的信息传递对象,其中,编号为i的同学的信息传递对象是编号为Ti同学. 游戏开始时,每人都只知道自己的生日.之后每一 ...
- NOIP 2015 信息传递
kawayi 题目描述 有n个同学(编号为1到n)正在玩一个信息传递的游戏.在游戏里每人都有一个固定的信息传递对象,其中,编号为i的同学的信息传递对象是编号为Ti同学. 游戏开始时,每人都只知道自己的 ...
随机推荐
- java线程同步问题
Java面试当中,线程可以说是必考内容,在看面试题的时候发现一遍很全的讲解Java面试题的博客:http://blog.csdn.net/csh624366188/article/details/80 ...
- ExtJS5_自定义菜单2
这一节来定义另外三种类型的菜单类.首先定义菜单按钮类.文件放于app/view/main/region目录下面,文件名为ButtonMainMenu.js. /** * 显示在顶部的按钮菜单,可以切换 ...
- C++进阶阅读
推荐的阅读顺序:level 1从<<essential c++>>开始,短小精悍,可以对c++能进一步了解其特性以<<c++ primer>>作字典和课 ...
- Node.js stream 流学习
由于node.js 创建http 是这样的 http.createServer(function(request,response){}).listen(2000); 里面的request 就是rea ...
- 【Maven实战】依赖的聚合和版本管理
1.在之前的文章中,我们已经建立了四个Maven项目,但是此时如果我们要对这四个项目进行编译打包时,必须一个一个的进行执行命令,而聚合就是指只要我们在其中一个项目中编写一些代码,则在进行此项目的编译和 ...
- 来晚了--SALTSTACK要弄起
PUPPET就算了,我多少都有PYTHON基础,还是专SALTSTACK吧. 今天小玩玩,以后深入.
- Callback函数详解(我感觉,回掉函数的本质是函数指针,在业务做循环处理的时候,调用一下通知外部)
2010年的最后一天了,转载一篇自己认为还不错的文章与大家分享.希望对大家有所帮助. 一,回调函数 我们经常在C++设计时通过使用回调函数可以使有些应用(如定时器事件回调处理.用回调函数记录某操作进度 ...
- BZOJ1715: [Usaco2006 Dec]Wormholes 虫洞
1715: [Usaco2006 Dec]Wormholes 虫洞 Time Limit: 5 Sec Memory Limit: 64 MBSubmit: 475 Solved: 263[Sub ...
- freemarker对数字的处理
freemark会默认对数字进行格式化处理,例如price = 12000, 通过${price}显示为12,000, 但其实有些场景会有问题: 比如编辑一条记录, 再保存,容易将12,000传到 ...
- hibernate初涉
好久都不曾写写总结一些东西了,惰性真的是令人难以克制!虽然和许多北漂族一样,艰苦而又迷茫,但是我总能找到一些方向,一点期盼,因为你就我的目标.我会坚持下去,重拾青春的热血,既然人生如戏,那我不当猪脚. ...