- 信息传递
- 2016-08-16 15:36:08 @
/*
NOIP2015
Day1 T2
信息传递
图论,最小环
*/
#include <cstdio>
#include <cstring>
#include <queue>
#define INF 999999
using namespace std;
int main(){
//freopen("in.in", "r", stdin);
int n,sendto[200001],visited[200001],entd[200001],ans = INF;
memset(visited, 0, sizeof(visited));
memset(entd, 0, sizeof(entd));
scanf("%d",&n);
queue<int> q;
for(int i = 1; i <= n;i++){
scanf("%d",&sendto[i]);
entd[sendto[i]]++; //其接受信息者入度加1
}
//读入数据及初始化
for(int i = 1; i <= n;i++){
if(!entd[i]){
visited[i] = 1;
q.push(i);
}
}
while(!q.empty()){
int cur = q.front();
q.pop();
entd[sendto[cur]]--;
if(!entd[sendto[cur]]){
visited[sendto[cur]] = 1;
q.push(sendto[cur]);
}
}
//宽搜去除无用结点
//接下来,判断剩余结点所组成的环,以此来计算游戏进行轮数:当某个点被访问时,轮数+1,直到环内某个节点在该环内被两次访问时,该环计算结束,以此类推,最后输出轮数最小值
for(int i = 1;i <=n;i++){
if(!visited[i] && entd[i]){
visited[i]++;
int curnode = sendto[i]; //将当前判断的结点初始化为结点i所指结点(如果初始化成结点i那么下面的那个while循环将无法执行)
int curans = 1;//记录当前环所经过的轮数,因为当前结点初始化成了i结点的下一个结点,就相当于结点i这个人把信息传递给了curnode(curnode当前值为sendto[i]),所以轮数已经有一轮了,就从1开始;
while(!visited[curnode]){ //当前结点没有被访问,那么就继续传递给下一个人,直到某个人被访问两次为止
visited[curnode]++;
++curans;//curnode传递信息给下一个人了,轮数+1
curnode = sendto[curnode]; //换成下一个结点继续判断
}
if(curans < ans) ans = curans;//若当前环的轮数比最小值小,就更新最小值,即答案。
}
//直到所有环都被判断完
}
printf("%d\n",ans);//输出答案
// printf("%d ms\n",(int)((double)clock()/CLOCKS_PER_SEC*1000));
return 0;
}
求帮看下,谢谢各位
个人感觉应该不能RE啊……数组开的也够大……
1 条评论
-
yujingbin LV 6 @ 2016-08-19 12:58:23
已重测,该代码没问题,已AC
- 1
信息
- ID
- 1979
- 难度
- 6
- 分类
- (无)
- 标签
- 递交数
- 4096
- 已通过
- 980
- 通过率
- 24%
- 被复制
- 9
- 上传者