• BZOJ 1051: [HAOI2006]受欢迎的牛


    Description

    一个有向图,求所以能被别的点到达的点的个数.

    Sol

    Tarjan + 强连通分量 + 缩点.

    缩点以后找强连通分量,缩点,然后当图有且仅有1个出度为1的点时,有答案.

    Code

    /**************************************************************
        Problem: 1051
        User: BeiYu
        Language: C++
        Result: Accepted
        Time:80 ms
        Memory:3044 kb
    ****************************************************************/
     
    #include<cstdio>
    #include<stack>
    #include<vector>
    #include<iostream>
    using namespace std;
        
    const int N = 10005;
    #define debug(a) cout<<#a<<"="<<a<<" "
    #define ct cout<<endl
    #define _ct cout<<"----------"<<endl
        
    int n,m,cnt,bcnt;
    int dfsn[N],low[N],ins[N],b[N],sz[N];
    vector<int> g[N];
    vector<int> h[N];
    stack<int> stk;
    struct Edge{ int fr,to; }edge[N*5];
        
    inline int in(int x=0,char ch=getchar()){ while(ch>'9'||ch<'0') ch=getchar();
        while(ch>='0'&&ch<='9') x=(x<<3)+(x<<1)+ch-'0',ch=getchar();return x; }
    void Tarjan(int u){
        dfsn[u]=low[u]=++cnt,ins[u]=1,stk.push(u);
        for(int i=0,lim=g[u].size(),v;i<lim;i++){
            v=g[u][i];
            if(!dfsn[v]){ Tarjan(v),low[u]=min(low[u],low[v]); }
            else if(ins[v]) low[u]=min(low[u],dfsn[v]);
        }if(dfsn[u]==low[u]){
            ++bcnt;int v;
            for(;;){ v=stk.top(),stk.pop(),ins[v]=0,b[v]=bcnt,sz[bcnt]++;if(u==v) break; }
        }
    }
    int main(){
    //  freopen("in.in","r",stdin);
        n=in(),m=in();
        for(int i=1,u,v;i<=m;i++) u=in(),v=in(),g[u].push_back(v),edge[i]=(Edge){ u,v };
        for(int i=1;i<=n;i++) if(!dfsn[i]) Tarjan(i);
    //  _ct;debug(bcnt),ct;
        for(int i=1,u,v;i<=m;i++){
            u=edge[i].fr,v=edge[i].to;
    //      debug(u),debug(v),ct;
    //      debug(b[u]),debug(b[v]),ct;
            if(b[u]!=b[v]) h[b[u]].push_back(b[v]);
        }
    //  _ct;
        int tmp=0,ans=0;
        for(int i=1;i<=bcnt;i++){
            if(h[i].size()==0) ans=sz[i],tmp++;
        }
        if(tmp!=1) putchar('0');else printf("%d",ans);
        return 0;
    }
    

      

      

  • 相关阅读:
    只要肯下功夫,十岁也能学得会的 Docker 精简版!
    sprintf和sscanf的用法
    ubuntu在线安装vscode
    Makefile模板
    本地Git配置绑定远程Github账户
    mysql多表查询
    VS error 2019 错误
    Oracle--约束
    Oracle--增删查
    Oracle--子查询
  • 原文地址:https://www.cnblogs.com/beiyuoi/p/5928017.html
Copyright © 2020-2023  润新知