• [Noip2015] 信息传递


    我知道这道题有多种解法,甚至暴力都可以满分,但是我在这里要介绍强连通分量的解法。

    这题的题意太简单了,就是说每个人把自己的生日告诉别人,知道从别人的嘴里知道自己的生日。

    很显然,一共进行的轮数就是最小的强连通分量的元素个数,因为如果形成了一个强连通分量,每个点都是可以相互到达的,所以结束肯定就是最早听到自己生日的那一次。

    所以我们要求元素最小的那个强连通分量

    代码:

     1 #include<algorithm>
     2 #include<cstdio>
     3 using namespace std;
     4 int son[200001],n,m,ans=999999999,group,low[200001],dfn[200001],st[200001],tot,now[200010],used[200001],popp[200001],a[200010],b[200010];
     5 void add(int x,int y)
     6 {
     7     tot++;
     8     now[tot]=son[x];
     9     son[x]=tot;
    10 }
    11 int top,sum,cnt,totle;
    12 void dfs(int deep)
    13 {
    14     st[++top]=deep;
    15     dfn[deep]=++cnt;
    16     low[deep]=dfn[deep];
    17     int nnow=top;
    18     for(int i=son[deep];i;i=now[i])
    19         if(!used[b[i]])
    20         {
    21             if(!dfn[b[i]])
    22                 dfs(b[i]);
    23             low[deep]=min(low[b[i]],low[deep]);
    24         }
    25     if(dfn[deep]==low[deep])
    26     {
    27         totle++;
    28         if(top-nnow)ans=min(top-nnow+1,ans);
    29         for(int i=nnow;i<=top;i++)
    30             used[st[i]]=totle;
    31         top=nnow-1;
    32     }
    33 }
    34 int main()
    35 {
    36     scanf("%d",&n);
    37     for(int i=1;i<=n;i++)
    38         scanf("%d",&b[i]),add(i,b[i]);
    39     for(int i=1;i<=n;i++)
    40         if(!used[i])dfs(i);
    41     printf("%d",ans);
    42 }
  • 相关阅读:
    物理材质
    铰链joints
    unity 刚体
    扩展方法
    转换操作符方法(非基元类型转换)
    向方法传递可变数量的参数
    参数:可选参数和命名参数
    实例构造器与值类型和引用类型、类型构造器
    成员的可访问性,友元程序集,静态类
    如何删除github上项目的文件
  • 原文地址:https://www.cnblogs.com/lcxer/p/9441703.html
Copyright © 2020-2023  润新知