• 洛谷 P2661 信息传递


    这题好久前就做过了...结果过了几个月还是不会...题解也看不懂...不过参考题解的一部分倒是懂了。

    首先把每个人当做一个节点,从每个人向他要告诉的那个人连边,产生一张有向图。显然,一个人如果不在环上,那么就永远不可能听到自己的信息;一个人如果在环上,那么就会在进行“包含这个点的长度最小的环的长度"轮之后听到自己的信息。现在要求所有人听到自己信息的轮数的最小值,也就是要求图的最小环。

    裸的最小环应该是floyed,$O(n^3)$。显然是不行的。可以注意到一点,就是这题的图中每个点最多只有一条出边。那么,一个点显然不可能出现在多个环里面。也就是说,一个点要么不在环中,要么只在一个单独的环中。因此,可以先把不在环上的点去掉;对于每个环,只需要从环上任意一点出发dfs一遍求出回到自身路径长度就行。

    如何把不在环上的点去掉?可以用拓扑排序。拓扑排序做一遍只会留下环上点。

    错误记录:

    1.deque不会用,47行写成pop_back()

    2.写题过程中记错题意,58行写成max

     1 //#pragma comment(linker, "/STACK:10240000,10240000")
     2 #include<cstdio>
     3 //#pragma GCC optimize (2)
     4 #include<deque>
     5 #include<malloc.h>
     6 using namespace std;
     7 struct E
     8 {
     9     int to,nxt;
    10 }e[400100];
    11 int f1[200100],ne,in[200100];
    12 deque<int> q;
    13 bool boo[200100];
    14 int n,ans=0x3f3f3f3f;
    15 int dfs(int x)
    16 {
    17     boo[x]=1;
    18 //    if(dep==43429)    
    19 //    {
    20 //        printf("1");
    21 //    }
    22     for(int k=f1[x];k!=0;k=e[k].nxt)
    23         if(!boo[e[k].to])
    24             return dfs(e[k].to)+1;
    25 }
    26 int main()
    27 {
    28     //int size = 256 << 20; // 256MB  //windows上可能需要手动扩栈,不然会爆栈
    29     //char *p = (char*)malloc(size) + size;  
    30     //__asm__("movl %0, %%esp
    " :: "r"(p));
    31     //freopen("testdata.in","r",stdin);
    32     int i,a,t,k;
    33     scanf("%d",&n);
    34     for(i=1;i<=n;i++)
    35     {
    36         scanf("%d",&a);
    37         e[++ne].to=a;
    38         e[ne].nxt=f1[i];
    39         f1[i]=ne;
    40         in[a]++;
    41     }
    42     for(i=1;i<=n;i++)
    43         if(in[i]==0)
    44             q.push_back(i);
    45     while(!q.empty())
    46     {
    47         t=q.front();q.pop_front();
    48         boo[t]=1;
    49         for(k=f1[t];k!=0;k=e[k].nxt)
    50         {
    51             in[e[k].to]--;
    52             if(in[e[k].to]==0)
    53                 q.push_back(e[k].to);
    54         }
    55     }
    56     for(i=1;i<=n;i++)
    57         if(!boo[i])
    58             ans=min(ans,dfs(i)+1);
    59     printf("%d",ans);
    60     return 0;
    61 }
  • 相关阅读:
    js日期加减得到新的日期的自定义函数
    c# winform 一个可以用鼠标改变控件位置和大小的类,调用即可
    颜色英文代码全集
    你的Web系统有多少安全漏洞
    robots协议和禁止搜索引擎收录
    Linux下./configure错误详解
    c# winform 关于DataGridView的一些操作
    通过JSONP实现完美跨域
    tabs选项卡
    jQuery 1.4的十五大新功能实例精讲
  • 原文地址:https://www.cnblogs.com/hehe54321/p/7810846.html
Copyright © 2020-2023  润新知