• bzoj 1051


    如果A认为B是受欢迎的,B认为C是受欢迎的,C认为A是受欢迎的,这时形成了一个环。

    这时如果A认为D是受欢迎的,那么B和C也认为D是受欢迎的。

    于是要考虑缩点。为了好打邻接表用了vector代替。推荐用Tarjan或者Gabow算法。

    缩点完最终只有可能有一个强连通分量的牛被全部牛认为是受欢迎的,或者直接没有。

    如果有超过一个的强连通分量的出度为0那么没有牛被全部牛认为是受欢迎的。

    否则就直接输出那个出度为0的强连通分量中牛的个数。

    #include<cstdio>
    #include<cctype>
    #include<algorithm>
    #include<vector>
    using namespace std;
    const int maxn=10001;
    const int maxm=50001;
    int read(){
        char c; while(!isdigit(c=getchar())); int x=c-'0';
        while(isdigit(c=getchar())) x=x*10+c-'0'; return x;
    }
    vector<int> e[maxn];
    int top,cnt,tme,vis[maxn],low[maxn],dfn[maxn],sta[maxn],num[maxn],dis[maxn],peo[maxn];
    void tarjan(int o){
        low[o]=vis[sta[++top]=o]=++tme;
        for(int i=0;i<e[o].size();i+=1)
            if(!dfn[e[o][i]]){
                if(!vis[e[o][i]]) tarjan(e[o][i]);
                low[o]=min(low[e[o][i]],low[o]);
            }
        if(vis[o]==low[o]){
            ++cnt;
            while(dfn[sta[top]]=cnt,peo[cnt]+=1,sta[top--]!=o);
        }
    }
    int main(){
        int n=read(),m=read(),ans=0;
        while(m--){
            int a=read(),b=read();
            e[a].push_back(b);
        }
        for(int i=1;i<=n;i+=1) if(!dfn[i]) tarjan(i);
        int tot=0,pre=0;
        for(int i=1;i<=n;i+=1)
            for(int j=0;j<e[i].size();j+=1)
                if(dfn[i]!=dfn[e[i][j]]) dis[dfn[i]]=1;
        for(int i=1;i<=cnt;i+=1) if(!dis[i]) tot+=1,pre=i;
        if(tot==1) printf("%d",peo[pre]); else printf("0");
        return 0;
    }
  • 相关阅读:
    正斜杠/和反斜杠的区别
    Ghost文件封装说明
    装机自动化脚本介绍
    ubuntu 11.04侧边栏怎么添加图标
    samba的安装和配置
    vim使用大全
    ubuntu中运行python脚本
    ubuntu中使用usb-creator制作live usb
    ubuntu中安装ftp服务器
    ubuntu命令查询版本和内核版本
  • 原文地址:https://www.cnblogs.com/AmnesiacVisitor/p/7657623.html
Copyright © 2020-2023  润新知