• 信息传递


     1 /*把每个同学都看成点,A同学将信息传给B同学,就相当于在A和B之间建立了一条有向边,将其加
     2 入并查集中,当遇到两个点的祖先节点相同时,则说明他们已经在同一个集合,那么就能构成环,此时
     3 判断一下环的长度即可。这里要用一个d[]数组,保存第i个节点到其祖先节点的距离。A和B所在集合
     4 构成环的长度就是d[a]+d[b]+1。*/
     5 //这段代码借鉴网上别的大神写的代码
     6 #include<iostream>
     7 using namespace std;
     8 int f[200002],d[200002],n,minn,last;   //f保存祖先节点,d保存到其祖先节点的路径长。 
     9 int fa(int x)
    10 {
    11     if (f[x]!=x)                       //查找时沿途更新祖先节点和路径长。 
    12     {
    13         int last=f[x];                 //记录父节点(会在递归中被更新)。 
    14         f[x]=fa(f[x]);                 //更新祖先节点。 
    15         d[x]+=d[last];                 //更新路径长(原来连在父节点上)。 
    16     }
    17     return f[x];
    18 }
    19 void check(int a,int b)
    20 {
    21     int x=fa(a),y=fa(b);               //查找祖先节点。 
    22     if (x!=y) 
    23         {
    24                f[x]=y;
    25               d[a]=d[b]+1;
    26          }   //若不相连,则连接两点,更新父节点和路径长。 
    27     else minn=min(minn,d[a]+d[b]+1);   //若已连接,则更新最小环长度。 
    28     return;
    29 }
    30 int main()
    31 {
    32     int i,t;
    33     scanf("%d",&n);
    34     for (i=1;i<=n;i++) f[i]=i;         //祖先节点初始化为自己,路径长为0。 
    35     minn=0x7777777;
    36     for (i=1;i<=n;i++)
    37     {
    38         scanf("%d",&t);
    39         check(i,t);                    //检查当前两点是否已有边相连接。 
    40     } //注意这里i和t的顺序一定不能换。
    41     printf("%d",minn);
    42     return 0;
    43 }
    44                 
  • 相关阅读:
    flex属性导图
    html代码换行造成空格间距问题
    iconfont作用在css伪类中的写法
    JS模态框 简单案例
    JS实时获取输入框中的值
    JS封装addClass、removeClass
    特效 左右滑动轮播图jQuery思路
    JS 字符串两边截取空白的trim()方法的封装
    JavaScript易混淆知识点小回顾--数组方法与字符串方法;
    用GitHub来展示前端页面
  • 原文地址:https://www.cnblogs.com/geziyu/p/9602059.html
Copyright © 2020-2023  润新知