tarjan condensing point - on the Farm farm Halloween Trick or Treat

A room to go to another room, there are cows to start drawing from their own point number (1 to n), if you return to the previous point had to stop and ask each cow can go through a few points;

 

Case two,

A cow on the ring, can take the size of the ring, two, one strand is connected a ring size chain ring +;

To answer from pretreated ring (1), as well as the size of the ring is (not point on the ring) is 1;

Initially thought possible only a chain does not ring, but because each point has a side out, so do not worry;

#include<cstdio>
#include<cstring>
#include<stack>
#include<algorithm>
using namespace std;
const int maxn=1e5+10;
int pre[maxn*2],last[maxn],other[maxn*2],l;
stack<int> s;
void add(int x,int y)
{
    l++;
    pre[l]=last[x];
    last[x]=l;
    other[l]=y;
}
int belong[maxn];
int qw;
int n;
int ru[maxn];
int cnt,dfn[maxn],low[maxn];
int next[maxn];

void dfs(int x)
{
    s.push(x);
    dfn[x]=low[x]=++cnt;
    ru[x]=1;
    for(int p=last[x];p;p=pre[p])
    {
        int v=other[p];
        if(!dfn[v])
        {
            dfs(v);
            low[x]=min(low[x],low[v]);
        }
        else if(ru[v])
        {
            low[x]=min(low[x],dfn[v]);
        }
    }
    if(dfn[x]==low[x])
    {
        belong[x]=++qw;
        while(!s.empty())
        {
            int y=s.top();
            s.pop();
            ru[y]=0;
            belong[y]=qw;
            if(y==x) break;
        }
    }
}
int ring[maxn];
int ans[maxn];

void search(int x,int y,int stp)
{
    if(ans[y])
    {
        ans[x]=ans[y]+stp;
        return ;
    }
    else search(x,next[y],stp+1);
}

int main()
{
    scanf("%d",&n);
    for(int i=1;i<=n;i++)
    {
        scanf("%d",&Next [I]); 
        the Add (I, Next [I]);
        IF (Next [I] == I) ANS [I] = . 1 ; 
    } 
    
    for ( int I = . 1 ; I <= n-; I ++) IF DFS (I) (DFN [I]!); // must pay attention to FIG Unicom not necessarily 
    for ( int I = . 1 ; I <= n-; I ++ ) 
    { 
        ring [belong [I]] ++; // size of the recording ring 
    }
     for ( int I = . 1 ; I <= n-; I ++ ) 
    { 
        IF (Ring [belong [I]] =! . 1 ) ANS [I] = Ring [belong [I]]; 
    } 
    for ( int I =1;i<=n;i++)
    {
        if(!ans[i]) search(i,next[i],1);
    }
    for(int i=1;i<=n;i++)
    {
        printf("%d\n",ans[i]);
    }
    return 0;
}

 

Guess you like

Origin www.cnblogs.com/WHFF521/p/11526185.html