zoukankan      html  css  js  c++  java
  • 【bzoj1589/Usaco2008 Dec】Trick or Treat on the Farm 采集糖果——拓扑排序

    Description

    每年万圣节,威斯康星的奶牛们都要打扮一番,出门在农场的N(1≤N≤100000)个牛棚里转悠,来采集糖果.她们每走到一个未曾经过的牛棚,就会采集这个棚里的1颗糖果. 农场不大,所以约翰要想尽法子让奶牛们得到快乐.他给每一个牛棚设置了一个“后继牛棚”.牛棚i的后继牛棚是Xi.他告诉奶牛们,她们到了一个牛棚之后,只要再往后继牛棚走去,就可以搜集到很多糖果.事实上这是一种有点欺骗意味的手段,来节约他的糖果.  第i只奶牛从牛棚i开始她的旅程.请你计算,每一只奶牛可以采集到多少糖果.

    Input

        第1行输入N,之后一行一个整数表示牛棚i的后继牛棚Xi,共N行.

    Output

        共N行,一行一个整数表示一只奶牛可以采集的糖果数量.

    Sample Input

    4 //有四个点
    1 //1有一条边指向1
    3 //2有一条边指向3
    2 //3有一条边指向2
    3

    INPUT DETAILS:

    Four stalls.
    * Stall 1 directs the cow back to stall 1.
    * Stall 2 directs the cow to stall 3
    * Stall 3 directs the cow to stall 2
    * Stall 4 directs the cow to stall 3

    Sample Output

    1
    2
    2
    3

    HINT

    Cow 1: Start at 1, next is 1. Total stalls visited: 1. Cow 2: Start at 2, next is 3, next is 2. Total stalls visited: 2. Cow 3: Start at 3, next is 2, next is 3. Total stalls visited: 2. Cow 4: Start at 4, next is 3, next is 2, next is 3. Total stalls visited: 3.


    一般的做法就是trajan环缩点,但考虑到每个点的后继只有一个,那么环中的点就不存在一条边指向环外的点(基环树)。

    那么如果我们把边反过来,从环开始逆拓扑一下,每往上走一步就答案+1即可。

    代码:

     1 #include<cstdio>
     2 #include<cstring>
     3 #include<queue>
     4 #include<algorithm>
     5 #define mem(a,p) memset(a,p,sizeof(a))
     6 const int N=1e5+10;
     7 int n,dfn[N],first[N],sz,dd[N],a[N];
     8 int cc[N],ne[N],q[N],t=0,h=1,an[N];
     9 bool ok[N];
    10 int read(){
    11     int ans=0,f=1;char c=getchar();
    12     while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
    13     while(c>='0'&&c<='9'){ans=ans*10+c-48;c=getchar();}
    14     return ans*f;
    15 }
    16 int main(){
    17     int n=read(),tot=0;
    18     for(int i=1;i<=n;i++){
    19         a[i]=read();ne[i]=first[a[i]];first[a[i]]=i;cc[i]++;
    20     }
    21     for(int i=1;i<=n;i++){
    22         if(ok[i])continue;
    23         ok[i]=1;dfn[i]=++tot;dd[tot]=i;int to=a[i];
    24         while(!ok[to]){
    25             dfn[to]=++tot;dd[tot]=to;
    26             ok[to]=1;to=a[to];
    27         }
    28         sz=tot-dfn[to]+1;
    29         for(int i=tot;i>=dfn[to];i--){
    30             int li=dd[i];cc[li]=0;an[li]=sz;
    31             for(int j=first[li];j;j=ne[j])if(dfn[j]<dfn[to])q[++t]=j,an[j]=sz+1;
    32         }
    33         while(h<=t){
    34             int x=q[h];h++;ok[x]=1;
    35             for(int i=first[x];i;i=ne[i]){
    36                 an[i]+=an[x]+1;
    37                 cc[i]--;if(!cc[i])q[++t]=i;
    38             }
    39         }
    40     }
    41     for(int i=1;i<=n;i++)printf("%d
    ",an[i]);
    42     return 0;
    43 }
    bzoj1589
  • 相关阅读:
    工作计划
    bzoj3626:[LNOI2014]LCA
    bzoj3631:[JLOI2014]松鼠的新家
    bzoj3573: [Hnoi2014]米特运输
    bzoj4027,[HEOI2015]兔子与樱花
    bzoj3624,[Apio2008]免费道路
    bzoj2208连通数
    tyvj1153/洛谷P1262间谍网络
    Application server libraries not found && IntelliJ IDEA && tomcat
    debian9安装java8
  • 原文地址:https://www.cnblogs.com/JKAI/p/7663502.html
Copyright © 2011-2022 走看看