zoukankan      html  css  js  c++  java
  • HNOI2006——受欢迎的牛(强连通分量)

    描述
    每一头牛的愿望就是变成一头最受欢迎的牛。现在有N头牛,给你M对整数(A,B),表示牛A认为牛B受欢迎。 这种关系是具有传递性的,如果A认为B受欢迎,B认为C受欢迎,那么牛A也认为牛C受欢迎。你的任务是求出有多少头牛被所有的牛认为是受欢迎的。
    输入
    第一行两个数N,M。 接下来M行,每行两个数A,B,意思是A认为B是受欢迎的(给出的信息有可能重复,即有可能出现多个A,B)
    输出
    一个数,即有多少头牛被所有的牛认为是受欢迎的。
    样例输入
    3 3
    1 2
    2 1
    2 3
    样例输出
    1
    提示
    数据范围
    10%的数据N<=20, M<=50
    30%的数据N<=1000,M<=20000
    70%的数据N<=5000,M<=50000
    100%的数据N<=10000,M<=50000

    先tarjan缩点

    显然一个强连通分量中如果有一头牛受某头牛欢迎

    那么分量中所有牛都是会受它欢迎的

    那么只需要缩点之后统计每个点的出度

    因为如果只有一个出度为0的点的话,那么这个点中所有牛都是被所以牛欢迎的

    考虑如果点uu出度不为0,则必定连向了另一个点vv

    如果点uu受所有牛欢迎,则必定有一条vv到该点的路径

    则必然构成一个环,与已经缩完点的条件不符

    而如果有两个出度为0的点,则这两个点一定不相连

    则没有牛受欢迎

    而如果图不连通

    则会存在2个及以上出度为0的点

    则答案为0

    #include<bits/stdc++.h>
    using namespace std;
    inline int read(){
        char ch=getchar();
        int res=0;
        while(!isdigit(ch))ch=getchar();
        while(isdigit(ch))res=(res<<3)+(res<<1)+(ch^48),ch=getchar();
        return res;
    }
    int n,m,adj[10005],nxt[50005],to[50005],vis[10005],dfn[10005],low[10005],bel[10005],belnum,in[10005],num[10006],ans,cnt,tot;
    inline void addedge(int u,int v){
        nxt[++cnt]=adj[u],adj[u]=cnt,to[cnt]=v;
    }
    stack<int> stk;
    inline void tarjan(int u){
        dfn[u]=low[u]=++tot;
        stk.push(u);
        for(int e=adj[u];e;e=nxt[e]){
            int v=to[e];
            if(!dfn[v]){
                tarjan(v);
                low[u]=min(low[u],low[v]);
                
            }
            else low[u]=min(low[u],dfn[v]);
        }
        if(dfn[u]==low[u]){
            belnum++;
            int tmp;
            do{
                tmp=stk.top();;
                stk.pop();
                vis[tmp]=0;
                bel[tmp]=belnum;
                num[belnum]++;
            }while(tmp!=u);
        }
    }
    int main(){
        n=read(),m=read();
        for(int i=1;i<=m;i++){
            int u=read(),v=read();
            addedge(u,v);
        }
        for(int i=1;i<=n;i++){
            if(!dfn[i])tarjan(i);
        }
        for(int u=1;u<=n;u++){
            for(int e=adj[u];e;e=nxt[e]){
                int v=to[e];
                if(bel[u]!=bel[v]){
                    in[bel[u]]++;
                }
            }
        }
        int tmp=0;
        for(int i=1;i<=belnum;i++){
            if(!in[i]){
                if(tmp){
                    cout<<0;
                    return 0;
                }
                tmp=i;
            }
        }
        cout<<num[tmp];
        return 0;
    }
    
    
  • 相关阅读:
    Win32中安全的子类化(翻译)
    OJ题目JAVA与C运行效率对比
    关协同过滤
    Objective-C ,ios,iphone开发基础:使用第三方库FMDB连接sqlite3 数据库,实现简单的登录
    GDI+简单现实文字旋转
    opencv 2.46与visual studio 2012 配置方法
    Emacs助力PowerShell
    ARC forbids explicit message send of 'autorelease'错误
    Event处理
    复制中发布服务器和订阅服务器内容不一致的解决办法
  • 原文地址:https://www.cnblogs.com/stargazer-cyk/p/10366432.html
Copyright © 2011-2022 走看看