zoukankan      html  css  js  c++  java
  • Trick or Treat on the Farm

    题目描述

    每年,在威斯康星州,奶牛们都会穿上衣服,收集农夫约翰在N(1<=N<=100,000)个牛棚隔间中留下的糖果,以此来庆祝美国秋天的万圣节。

    由于牛棚不太大,FJ通过指定奶牛必须遵循的穿越路线来确保奶牛的乐趣。为了实现这个让奶牛在牛棚里来回穿梭的方案,FJ在第i号隔间上张贴了一个“下一个隔间”Next_i(1<=Next_i<=N),告诉奶牛要去的下一个隔间;这样,为了收集它们的糖果,奶牛就会在牛棚里来回穿梭了。

    FJ命令奶牛i应该从i号隔间开始收集糖果。如果一只奶牛回到某一个她已经去过的隔间,她就会停止收集糖果。

    在被迫停止收集糖果之前,计算一下每头奶牛要前往的隔间数(包含起点)。

    输入格式

    第1行 整数n。

    第2行到n+1行 每行包含一个整数 next_i 。

    输出格式

    n行,第i行包含一个整数,表示第i只奶牛要前往的隔间数。

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

    code

    #include<stdio.h> 
    #include<string.h>
    #include<algorithm> 
    using namespace std;
    const int mxn=110000;
    struct Edge {
        int to,next;
    }edge[mxn];
    bool ins[mxn];
    int n,cnt,k,idx,top;
    int ans[mxn],val[mxn],bel[mxn],next[mxn];
    int stk[mxn],low[mxn],dfn[mxn],first[mxn];
    
    void add(int from,int to) 
    {
        edge[++cnt].to=to;
        edge[cnt].next=first[from];
        first[from]=cnt;
    }
    
    void Tarjan(int x) 
    {
        dfn[x]=low[x]=++idx;
        stk[++top]=x;
        ins[x]=1;
        for(int i=first[x];i;i=edge[i].next) {
            int to=edge[i].to;
            if(!dfn[to]) {
                Tarjan(to);
                low[x]=min(low[x],low[to]);
            }
            else if(ins[to]) {
                low[x]=min(low[x],low[to]);
            }
        }
        if(low[x]==dfn[x]) {
            ++k;
            int curr,len=0;
            do{
                ++len;
                curr=stk[top--];
                bel[curr]=k;
                ins[curr]=0;
            }while(curr!=x);
            val[k]=len;
        }
    }
    
    void serch(int root,int x,int stp) {
        if(ans[x]!=0) ans[root]=ans[x]+stp;
         else serch(root,next[x],stp+1);
    }
    
    int main() 
    {
        scanf("%d",&n);
        for(int i=1;i<=n;++i) 
        {
            scanf("%d",&next[i]);
            add(i,next[i]);
            if(i==next[i]) ans[i]=1;
        }
        for(int i=1;i<=n;++i) if(!dfn[i]) Tarjan(i);
        for(int i=1;i<=n;++i) 
            if(val[bel[i]]!=1) ans[i]=val[bel[i]];
        for(int i=1;i<=n;++i) 
            if(!ans[i]) serch(i,next[i],1);
        for(int i=1;i<=n;++i) {
            printf("%d
    ",ans[i]);
        }    
        return 0;
    }
  • 相关阅读:
    48. Rotate Image
    47. Permutations II
    46. Permutations
    45. Jump Game II
    44. Wildcard Matching
    43. Multiply Strings
    42. Trapping Rain Water
    41. First Missing Positive
    40. Combination Sum II
    39. Combination Sum
  • 原文地址:https://www.cnblogs.com/qseer/p/9825960.html
Copyright © 2011-2022 走看看