洛谷 信息传递之图中寻找最小环(图论)

有n个同学(编号为1到n)正在玩一个信息传递的游戏。在游戏里每人都有一个固定的信息传递对象,其中,编号为i的同学的信息传递对象是编号为Ti同学。

游戏开始时,每人都只知道自己的生日。之后每一轮中,所有人会同时将自己当前所知的生日信息告诉各自的信息传递对象(注意:可能有人可以从若干人那里获取信息,但是每人只会把信息告诉一个人,即自己的信息传递对象)。当有人从别人口中得知自己的生日时,游戏结束。请问该游戏一共可以进行几轮?

#include<bits/stdc++.h>

using namespace std;
const int MAXN = 200005;
int n,num[MAXN],ans = MAXN;
int used[MAXN],times[MAXN];
void dms(int x){//寻找最小环
    int clocks = 0,p = x;//p表示哪一个同学,clock是当前步数;
    while(true){//先执行,后作判断
        used[p] = x,times[p] = clocks ++,p = num[p];
        if(used[p]){if(used[p] == x) ans = min(ans,clocks - times[p]); break; }
    }

}

//此处以
5
2 4 2 3 1 数据为例
第一步:
used[1]=1;times[1]=0;clock=1;p=num[1]=2;p指向与1相连的2;
第二步:
used[2]=1;times[2]=1;clock=2;p=num[2]=4;p指向与2相连的4;
第三步:
used[4]=1;times[4]=2;clock=3;p=num[p]=3;p指向与4相连的3;
第四步:
used[3]=1;times[3]=3;clock=4;p=num[p]=2;p指向与3相连的2;
此后  used[2],used[2]=1;ans=4-1=3;
这时与1相连的成员全部遍历完全,后续只用遍历未与1相连的成员即可,ans不断更新最小值

int main()
{
    memset(times,0,sizeof(times));
    memset(used,0,sizeof(used));
    scanf("%d",&n);
    for(int i = 1; i <= n; i ++) scanf("%d",&num[i]);
    for(int i = 1; i <= n; i ++) if(!used[i]) dms(i);
    printf("%d\n",ans);
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值