# P2921 [USACO08DEC]在农场万圣节Trick or Treat on the Farm

## 题目描述

Every year in Wisconsin the cows celebrate the USA autumn holiday of Halloween by dressing up in costumes and collecting candy that Farmer John leaves in the N (1 <= N <= 100,000) stalls conveniently numbered 1..N.

Because the barn is not so large, FJ makes sure the cows extend their fun by specifying a traversal route the cows must follow. To implement this scheme for traveling back and forth through the barn, FJ has posted a 'next stall number' next_i (1 <= next_i <= N) on stall i that tells the cows which stall to visit next; the cows thus might travel the length of the barn many times in order to collect their candy.

FJ mandates that cow i should start collecting candy at stall i. A cow stops her candy collection if she arrives back at any stall she has already visited.

Calculate the number of unique stalls each cow visits before being forced to stop her candy collection.

POINTS: 100

## 输入输出格式

* Line 1: A single integer: N

* Lines 2..N+1: Line i+1 contains a single integer: next_i

* Lines 1..N: Line i contains a single integer that is the total number of unique stalls visited by cow i before she returns to a stall she has previously visited.

## 输入输出样例

4
1
3
2
3


1
2
2
3


## 说明

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

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.

#include<bits/stdc++.h>
using namespace  std;
const int maxn=100010;
int in[maxn],ans[maxn],next[maxn];//in[]表示此点的入度 ，next[]此点指向的下一个点，ans记录结果
int visit[maxn];
void del(int h)
{
visit[h]=1;
in[next[h]]--;
if(!in[next[h]]) //此链下 一个结点不存在其他的入度，继续删
del(next[h]);
}
int calcircle(int h,int depth)
{
ans[h]=depth;
if(ans[next[h]]) return depth;
else
return ans[h]=calcircle(next[h],depth+1);
}
int cal(int h)
{
if(ans[h]) return ans[h];//不在环上的点，ans[h]初值还为零
else return ans[h]=cal(next[h])+1;
}
int main()
{
int n;
cin>>n;
for(int i=1;i<=n;i++)
{
cin>>next[i];
in[next[i]]++;
}
for(int i=1;i<=n;i++)
if(!in[i]&&!visit[i])//删链
del(i);
for(int i=1;i<=n;i++)
if(in[i]&&!ans[i]) calcircle(i,1);//计算每个点在环上的大小
for(int i=1;i<=n;i++) if(!in[i]&&!ans[i]) cal(i);//计算不在环上的点
for(int i=1;i<=n;i++) cout<<ans[i]<<endl;
return 0;
}