[NOIP2015]Day1 T2 信息传递
来源:互联网 发布:金融数据分析基于r 编辑:程序博客网 时间:2024/06/04 19:45
题意:知道n个人以及他们信息传递的对象,每一轮传递一次自己知道的信息,问最少几轮使得某个人能听到自己的信息。
分析:果断按着样例画了一张有向图,如下:
样例输入
5
2 4 2 3 1
样例输出
3
这已经够明显了,很容易将题目转化为求有向图最小的环。因为只有形成了一个环,一个人的信息才有可能传递回自己,下面讲两种解法。
一、拓扑排序。每次将入度为0的点放入队列,再一个个遍历,我们知道环上的点是不会在拓扑序中的,故可将拓扑排序得到的点排除,因为它们不是环上的点,接下来遍历每个环就行了。
#include<stdio.h>#include<algorithm>#include<iostream>#define oo 2000000000#define M 200005using namespace std;template <class T>inline void Rd(T &res){ char c;res=0;int k=1; while(c=getchar(),c<48&&c!='-'); if(c=='-'){k=-1;c='0';} do{ res=(res<<3)+(res<<1)+(c^48); }while(c=getchar(),c>=48); res*=k;}int n,ans;int T[M];//记每个人的信息传递对象int degree[M];//记每个点的入读int Q[M],f[M],mark[M];int main(){ int L=0,R=0; Rd(n); for(int i=1;i<=n;i++){ Rd(T[i]); degree[T[i]]++;//增加传递对象入度 } for(int i=1;i<=n;i++) if(degree[i]==0)Q[R++]=i;//初始入度为0的点入队 while(L<R){ int u=Q[L++]; f[u]=1; int v=T[u]; degree[v]--; if(degree[v]==0)Q[R++]=v;//入度为0的点入队 } ans=oo; for(int i=1;i<=n;i++){//剩下的是环上的点,每次遍历一个环并将环上的点标记 if(f[i]||mark[i])continue; mark[i]=1; int k=i,res=1; while(T[k]!=i){ k=T[k]; mark[k]=1; res++; } if(res>1)ans=min(ans,res); } printf("%d\n",ans); return 0;}
二、强连通分量。我们知道每一个环都是一个强连通分量,故可直接把强连通分量敲上去。
#include<stdio.h>#include<string.h>#include<vector>#include<algorithm>#include<iostream>#define oo 2000000000#define M 200005using namespace std;template <class T>inline void Rd(T &res){ char c;res=0;int k=1; while(c=getchar(),c<48&&c!='-'); if(c=='-'){k=-1;c='0';} do{ res=(res<<3)+(res<<1)+(c^48); }while(c=getchar(),c>=48); res*=k;}vector<int>G[M];vector<int>rG[M];vector<int>vs;int used[M],belong[M];void add_edge(int u,int v){//每次建边的同时建一条反向边 G[u].push_back(v); rG[v].push_back(u);}void dfs(int u){//正向dfs used[u]=1; for(int i=0;i<G[u].size();i++){ int v=G[u][i]; if(!used[v])dfs(v); } vs.push_back(u);}void rdfs(int u,int cnt){//反向dfs used[u]=1; belong[u]=cnt; for(int i=0;i<rG[u].size();i++){ int v=rG[u][i]; if(!used[v])rdfs(v,cnt); }}int scc(int n){//求强连通分量 memset(used,0,sizeof(used)); for(int i=1;i<=n;i++) if(!used[i])dfs(i); memset(used,0,sizeof(used)); int cnt=0; for(int i=vs.size()-1;i>=0;i--) if(!used[vs[i]])rdfs(vs[i],++cnt); return cnt;}int n,cnt[M],ans;int main(){ int x; Rd(n); for(int i=1;i<=n;i++){ Rd(x); add_edge(i,x); } int V=scc(n); ans=oo; for(int i=1;i<=n;i++){ cnt[belong[i]]++; } for(int i=1;i<=V;i++) if(cnt[i]>1)ans=min(ans,cnt[i]); printf("%d\n",ans); return 0;}
刚看到这题的时候就想到要求环了,于是想敲强连通分量,但是不会敲,就敲臭了……
5555555~~~~~~~~~
0 0
- [NOIP2015]Day1 T2 信息传递
- codevs 4511 信息传递(NOIP2015 day1 T2)
- codevs 4511 信息传递 NOIP2015 day1 T2
- 信息传递 NOIP2015 提高组 Day1 T2
- codevs 4511 信息传递 NOIP2015 day1 T2
- [NOIP2015] 信息传递 D1 T2
- C++&Pascal——NOIP2015提高组day1 t2——信息传递
- Noip2015 Day1 T2 信息传递(虽然是图论题但是...)
- NOIP2015 提高组 day1 信息传递
- 【NOIP2015提高组Day1】信息传递
- NOIP2015 提高组 day1 信息传递
- JZOJsenior4324.【NOIP2015提高组Day1】信息传递
- NOIP2015提高组day1 —— 信息传递(message)
- NOIP2015 提高组 复赛 day1 message 信息传递
- Noip提高组2015 Day1 T2 信息传递 tarjan
- noip2015 day1 t2 message 伪·题解
- Noip2015 Day1 T2 子串(Dp)
- [NOIP2015]信息传递
- Foxmail与QQ邮箱关联创建新账户
- struts登陆验证(防止未登录的游客非法访问)
- 数组名作为函数参数以及sizeof用法
- 关于Windows高DPI的一些简单总结
- codeforces 233c Cycles【贪心】
- [NOIP2015]Day1 T2 信息传递
- 自动驾驶的核心技术之四:线控技术
- Spring MVC学习总结(11)——Spring MVC集成Swagger跨域问题
- PHP将数组写入文件
- MySQL的三大引擎:InnoDB、MyISAM和Memory
- netca.rsp详解
- 致每一位奋斗的年轻人
- bzoj3531: [Sdoi2014]旅行
- Maven生命周期及其他核心概念