zoukankan      html  css  js  c++  java
  • bzoj1529 [POI2005]ska Piggy banks

    Description

    Byteazar 有 N 个小猪存钱罐. 每个存钱罐只能用钥匙打开或者砸开. Byteazar 已经把每个存钱罐的钥匙放到了某些存钱罐里. Byteazar 现在想买一台汽车于是要把所有的钱都取出来. 他想尽量少的打破存钱罐取出所有的钱,问最少要打破多少个存钱罐. 

    Input

    第一行一个整数 N (1 <= N <= 1.000.000) – 表示存钱罐的总数. 接下来每行一个整数,第 i+1行的整数代表第i个存钱罐的钥匙放置的存钱罐编号. 

    Output

    一个整数表示最少打破多少个存钱罐.
    由存钱罐向钥匙所在存钱罐连边得到基环内向森林
    从a能到达b说明若打破b可以打开a
    因此答案为环的个数,拓扑排序求一下即可
    #include<cstdio>
    char buf[10000005],*ptr=buf-1;
    inline int input(){
        int x=0,c=*++ptr;
        while(c>57||c<48)c=*++ptr;
        while(c>47&&c<58)x=x*10+c-48,c=*++ptr;
        return x;
    }
    const int N=1000100;
    int n;
    int fa[N],q[N],in[N],ql=0,qr=0;
    bool ed[N];
    int main(){
        fread(buf,1,10000000,stdin);
        n=input();
        for(int i=1;i<=n;i++)++in[fa[i]=input()];
        for(int i=1;i<=n;i++)if(!in[i])q[qr++]=i;
        while(ql!=qr){
            int w=q[ql++];
            ed[w]=1;
            if(!--in[fa[w]])q[qr++]=fa[w];
        }
        int ans=0;
        for(int a=1;a<=n;a++)if(!ed[a]){
            int b=a;
            do{
                b=fa[b];
                ed[b]=1;
            }while(b!=a);
            ++ans;
        }
        printf("%d
    ",ans);
        return 0;
    }
  • 相关阅读:
    Python 异常处理
    Python File(文件) 方法
    python 文件定位
    globals() 和 locals() 函数
    python dir()函数
    python from…import* 语句
    python from…import 语句
    Python 模块
    python 匿名函数
    python 函数参数
  • 原文地址:https://www.cnblogs.com/ccz181078/p/5515091.html
Copyright © 2011-2022 走看看