首页 > 代码库 > 信息传递 NOIP2015 day1 T2
信息传递 NOIP2015 day1 T2
题文:
有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个整数,表示游戏一共可以进行多少轮。
这题目看上去是在找一个有向图的最小环,因为每个点只有一个出度,所以图中不可能出现强连通分量中套着
强连通分量的情况,所以我们只要跑遍tarjian,统计每个分量的size就可以了;
但是n平方的算法为啥没T掉,求解;
AC代码:
#include<stdio.h> #include<stdlib.h> #include<iostream> #include<cstring> #include<stack> #include<algorithm> using namespace std; const int MAXN=2000020; int n,num=0,num1=0; int dfn[MAXN],low[MAXN]; bool in[MAXN]; int ans=1<<30; struct edge{ int first; int next; int quan; int to; }a[MAXN]; void addedge(int from,int to){ a[++num].to=to; a[num].next=a[from].first; a[num].quan=1; a[from].first=num; } stack<int> q; void tarjian(int now){ dfn[now]=low[now]=num1++; in[now]=1; q.push(now); for(int i=a[now].first;i;i=a[i].next){ int to=a[i].to; if(!dfn[to]){ tarjian(to); low[now]=min(low[now],low[to]); } else if(in[to]){ low[now]=min(low[now],dfn[to]); } } if(low[now]==dfn[now]){ int u=-1,size=0; while(u!=now){ u=q.top(); q.pop(); in[u]=0; size++; } if(size!=1) ans=min(ans,size); } } int main() { memset(in,0,sizeof(in)); while(!q.empty()) q.pop(); cin>>n; for(int i=1;i<=n;i++){ int x; scanf("%d",&x); addedge(i,x); } for(int i=1;i<=n;i++){ if(!dfn[i]){ tarjian(i); } } printf("%d",ans); }
信息传递 NOIP2015 day1 T2
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。