码迷,mamicode.com
首页 > 其他好文 > 详细

P2661 信息传递

时间:2018-08-30 16:53:18      阅读:166      评论:0      收藏:0      [点我收藏+]

标签:cstring   节点   etc   math   int   来源   +=   i++   解释   

题意:

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

 

输入输出样例

输入样例
5
2 4 2 3 1
输出样例
3

说明

样例1解释

技术分享图片

游戏的流程如图所示。当进行完第3 轮游戏后, 4号玩家会听到 2 号玩家告诉他自己的生日,所以答案为 3。当然,第 3 轮游戏后,2号玩家、 3 号玩家都能从自己的消息来源得知自己的生日,同样符合游戏结束的条件。

对于 30%的数据, n ≤ 200

对于 60%的数据, n ≤ 2500

对于100%的数据, n ≤ 200000

 

 

并查集判最小环

 

假设信息由A传递给B,那么就连一条由A指向B的边,同时更新A的父节点,A到它的父节点的路径长也就是B到它的父节点的路径长+1。

 

这样我们就建立好了一个图,之后信息传递的所有环节都按照这些路径。游戏结束的轮数,也就是这个图里最小环的长度。

 

如果有两个点祖先节点相同,那么就可以构成一个环,长度为两个点到根节点长度之和+1。

 

#include<cstdio>
#include<iostream>
#include<cstring>
#include<cctype>
#include<algorithm>
using namespace std;
#define olinr return
#define _ 0
#define love_nmr 0
#define DB double
inline int read()
{
    int x=0,f=1;
    char ch=getchar();
    while(!isdigit(ch))
    {
        if(ch==-)
            f=-f;
        ch=getchar();
    }
    while(isdigit(ch))
    {
        x=(x<<1)+(x<<3)+(ch^48);
        ch=getchar();
    }
    return x*f;
}
inline void put(int x)
{
    if(x<0)
    {
        x=-x;
        putchar(-);
    }
    if(x>9)
        put(x/10);
    putchar(x%10+0);
}
int f[205050];
int dis[205050];
int ans=0x7fffffff;
int n;
inline int findset(int x)
{
    if(x!=f[x])
    {
        int fa=f[x];
        f[x]=findset(f[x]);   //路径压缩 
        dis[x]+=dis[fa];    //记录到根的路径长
    }
    return f[x];
}
inline void doit(int x,int y)
{
    int xx=findset(x);   //找到根
    int yy=findset(y);
    if(xx!=yy)   //不在一个集合(不会得到自己生日的信息)
    {
        f[xx]=yy;
        dis[x]=dis[y]+1;
    }
    else
        ans=min(ans,dis[x]+dis[y]+1);  //求最小环长度
}
int main()
{
    n=read();
    for(int i=1;i<=n;i++)
        f[i]=i;
    for(int i=1;i<=n;i++)
        doit(i,read());
    put(ans);
    olinr ~~(0^_^0)+love_nmr;
}

 

P2661 信息传递

标签:cstring   节点   etc   math   int   来源   +=   i++   解释   

原文地址:https://www.cnblogs.com/olinr/p/9560686.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!