luogu2661 信息传递
2018-02-22 23:49
239 查看
http://www.elijahqi.win/2017/07/03/luogu2661/
题目:
有n个同学(编号为1到n)正在玩一个信息传递的游戏。在游戏里每人都有一个固定的信息传递对象,其中,编号为i的同学的信息传递对象是编号为Ti同学。
游戏开始时,每人都只知道自己的生日。之后每一轮中,所有人会同时将自己当前所知的生日信息告诉各自的信息传递对象(注意:可能有人可以从若干人那里获取信息,但是每人只会把信息告诉一个人,即自己的信息传递对象)。当有人从别人口中得知自己的生日时,游戏结束。请问该游戏一共可以进行几轮?
样例输入:
5 2 4 2 3 1
样例输出:
3
说明:
样例1解释
游戏的流程如图所示。当进行完第3轮游戏后,4号玩家会听到2号玩家告诉他自
己的生日,所以答案为3。当然,第3轮游戏后,2号玩家、3号玩家都能从自己的消息
来源得知自己的生日,同样符合游戏结束的条件。
对于 30%的数据, n ≤ 200;
对于 60%的数据, n ≤ 2500;
对于 100%的数据, n ≤ 200000。
强连通
1.tarjan求强连通分量
2.求出分量中>1且是最小的值输出即可
程序分析:拓扑排序
强连通计算分量 求大于一的最小值
直接暴力搜环(dfs)
通过拓补排序
题目:
有n个同学(编号为1到n)正在玩一个信息传递的游戏。在游戏里每人都有一个固定的信息传递对象,其中,编号为i的同学的信息传递对象是编号为Ti同学。
游戏开始时,每人都只知道自己的生日。之后每一轮中,所有人会同时将自己当前所知的生日信息告诉各自的信息传递对象(注意:可能有人可以从若干人那里获取信息,但是每人只会把信息告诉一个人,即自己的信息传递对象)。当有人从别人口中得知自己的生日时,游戏结束。请问该游戏一共可以进行几轮?
样例输入:
5 2 4 2 3 1
样例输出:
3
说明:
样例1解释
游戏的流程如图所示。当进行完第3轮游戏后,4号玩家会听到2号玩家告诉他自
己的生日,所以答案为3。当然,第3轮游戏后,2号玩家、3号玩家都能从自己的消息
来源得知自己的生日,同样符合游戏结束的条件。
对于 30%的数据, n ≤ 200;
对于 60%的数据, n ≤ 2500;
对于 100%的数据, n ≤ 200000。
强连通
1.tarjan求强连通分量
2.求出分量中>1且是最小的值输出即可
#include<cstdio> #include<cstring> using namespace std; int const N=220000; struct node{ int x,y,next; }; int num,stack ,dfn ,low ,h ,b ,top,s,n; bool stackf ; node data ; void insert1(int x,int y){ data[++num].x=x; data[num].y=y; data[num].next=h[x]; h[x]=num; } void tarjan(int u){ dfn[u]=++num; low[u]=num; stack[++top]=u; stackf[u]=true; for (int i=h[u];i;i=data[i].next){ int v=data[i].y; if (dfn[v]==0){ tarjan(v); if (low[v]<low[u]) low[u]=low[v]; }else{ if(stackf[v]&&dfn[v]<low[u]) low[u]=dfn[v]; } } if (low[u]==dfn[u]){ ++s; int y; do{ y=stack[top--]; stackf[y]=false; b[s]++; }while (y!=u); } } int main(){ freopen("message.in","r",stdin); freopen("message.out","w",stdout); scanf("%d",&n); num=0; memset(h,0,sizeof(h)); for (int i=1;i<=n;++i){ int t; scanf("%d",&t); insert1(i,t); } num=top=0; memset(stackf,false,sizeof(stackf)); memset(dfn,0,sizeof(dfn)); for (int i=1;i<=n;++i){ if (dfn[i]==0) tarjan(i); } int min=0x7fffffff; //printf("%d",b[1]); //memset(b,0,sizeof(b)); for (int i=1;i<=s;++i){ //printf("%d \n",b[i]); if (b[i]>1&&(min>b[i])) min=b[i]; } printf("%d",min); return 0; }
程序分析:拓扑排序
强连通计算分量 求大于一的最小值
直接暴力搜环(dfs)
通过拓补排序
#include<cstdio> #include<cstring> struct node{ int x,y,next; }; node data[220000]; bool stackf[220000]; int q[11000],h[220000],aa[220000],a[220000],n,num,min; void check(int u){ if (stackf[u]==false) return; int x=data[h[u]].x,y=data[h[u]].y; stackf[x]=false; min++; check(y); } int main(){ freopen("message.in","r",stdin); freopen("message.out","w",stdout); scanf("%d",&n); memset(h,0,sizeof(h)); num=0; memset(aa,0,sizeof(aa)); for (int i=1;i<=n;++i) { scanf("%d",&a[i]); aa[a[i]]++; data[++num].x=i; data[num].y=a[i]; data[num].next=h[i]; h[i]=num; } int op=0,cl=0; for (int i=1;i<=n;++i) if (aa[i]==0) { q[++cl]=i; } //拓补排序 while (op<cl){ ++op; if (op==11000) op=0; for (int i=h[q[op]];i;i=data[i].next){ int 4000 x=data[i].x,y=data[i].y; aa[y]--; if (aa[y]==0) { ++cl; if (cl==11000) cl=0; q[cl]=y; } } } memset(stackf,true,sizeof(stackf)); int ans=0x7fffffff; for (int i=1;i<=n;++i){ min=0; if(aa[i]!=0){ check(i); } if (min<ans&&min!=0) ans=min; } printf("%d",ans); return 0; }
相关文章推荐
- Luogu2661 信息传递(图论)
- 洛谷2661 信息传递
- 洛谷P2661 信息传递==coedevs4511 信息传递 NOIP2015 day1 T2
- 信息传递(洛谷 2661)
- 洛谷2661 信息传递
- 【洛谷2661】信息传递 强联通分量
- NOIp2015TG/Luogu P2661 信息传递 解题报告
- 【NOIP2015】洛谷2661 信息传递
- Android中页面跳转,并传递信息
- angular模块和组件之间传递信息和操作流程的方法(笔记)
- 洛谷P2661 信息传递 (NOIp2015)
- 网络基础之信息的生成与传递
- shuffle过程中的信息传递
- 【GLSL教程】(三)在OpenGL中向shader传递信息
- 跨域信息传递postMessage
- shiro 无法传递及接收cookie信息
- Fragment与Acticity的信息传递 || Fragment之间的信息传递
- 洛谷 P2661 信息传递
- WCF后续之旅(6): 通过WCF Extension实现Context信息的传递
- [NOIP 2015]Day.1 T2 信息传递 【最小环】