1. 程式人生 > >[BZOJ1589][Usaco2008 Dec]Trick or Treat on the Farm 采集糖果

[BZOJ1589][Usaco2008 Dec]Trick or Treat on the Farm 采集糖果

ems data www. ont ble false 設置 elong col

1589: [Usaco2008 Dec]Trick or Treat on the Farm 采集糖果

Time Limit: 5 Sec Memory Limit: 64 MB Submit: 719 Solved: 408 [Submit][Status][Discuss]

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
縮點之後在DAG上遞推
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std; 
char buf[10000000], *ptr = buf - 1;
inline int readint(){
    int n = 0;
    char ch = *++ptr;
    while(ch < 0 || ch > 9) ch = *++ptr;
    while(ch <= 9 && ch >= 
0){ n = (n << 1) + (n << 3) + ch - 0; ch = *++ptr; } return n; } const int maxn = 200000 + 10; struct Edge{ int to, next; Edge(){} Edge(int _t, int _n): to(_t), next(_n){} }e[maxn]; int fir[maxn] = {0}, cnt = 0; inline void add(int u, int v){ e[++cnt] = Edge(v, fir[u]); fir[u] = cnt; } int n; int dfn[maxn] = {0}, low[maxn], idx = 0; int belong[maxn], bcnt; int sta[maxn], top = 0; bool ins[maxn] = {false}; int f[maxn]; void tarjan(int u){ dfn[u] = low[u] = ++idx; sta[++top] = u; ins[u] = true; for(int v, i = fir[u]; i; i = e[i].next){ v = e[i].to; if(!dfn[v]){ tarjan(v); low[u] = min(low[u], low[v]); } else if(ins[v]) low[u] = min(low[u], dfn[v]); } if(low[u] == dfn[u]){ int now; bcnt++; f[bcnt] = 0; do{ now = sta[top--]; ins[now] = false; belong[now] = bcnt; f[bcnt]++; }while(now != u); } } int ind[maxn] = {0}; int q[maxn], h, t; void tsort(){ h = t = 0; for(int i = n + 1; i <= bcnt; i++) if(!ind[i]) q[t++] = i; int u, v; while(h != t){ u = q[h++]; for(int i = fir[u]; i; i = e[i].next){ v = e[i].to; ind[v]--; if(!ind[v]) q[t++] = v; } } for(int i = t - 1; ~i; i--){ for(int j = fir[q[i]]; j; j = e[j].next) f[q[i]] += f[e[j].to]; } } int main(){ fread(buf, sizeof(char), sizeof(buf), stdin); n = bcnt = readint(); for(int x, i = 1; i <= n; i++){ x = readint(); if(x != i) add(i, x); } for(int i = 1; i <= n; i++) if(!dfn[i]) tarjan(i); for(int i = 1; i <= n; i++) for(int j = fir[i]; j; j = e[j].next) if(belong[i] != belong[e[j].to]){ add(belong[i], belong[e[j].to]); ind[belong[e[j].to]]++; } tsort(); for(int i = 1; i <= n; i++) printf("%d\n", f[belong[i]]); return 0; }

[BZOJ1589][Usaco2008 Dec]Trick or Treat on the Farm 采集糖果