zoukankan      html  css  js  c++  java
  • [BZOJ1589][Usaco2008 Dec]Trick or Treat on the Farm 采集糖果

    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
    ", f[belong[i]]);
        return 0;
    }
  • 相关阅读:
    Python 递归
    Python 面向过程编程
    Python 协程函数
    Python-第三方库requests详解
    Python 三元表达式
    linux copy
    centos 安装软件
    mysql 权限
    mysql 权限 备份
    android 开发
  • 原文地址:https://www.cnblogs.com/ruoruoruo/p/7553473.html
Copyright © 2011-2022 走看看