HNOI2006——受欢迎的牛(强连通分量)

摘要:
描述每一头牛的愿望是成为最受欢迎的奶牛。现在有N头牛。给你M对整数(A,B),表明牛A认为牛B很受欢迎。你的任务是找出所有奶牛都认为有多少奶牛受欢迎。接下来,在M行中,每行中有两个数字A和B,这意味着A认为B是一个受欢迎的输出数字,即所有奶牛都认为有多少头牛受欢迎。

描述
每一头牛的愿望就是变成一头最受欢迎的牛。现在有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;
}

免责声明:文章转载自《HNOI2006——受欢迎的牛(强连通分量)》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇MATLAB实例:PCA(主成成分分析)详解SQLserver数据文件(MDF)的页面文件头结构剖析下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

linux下jcmd无法获取jvmdump

现象: 前两天在linux上的服务出现莫名其妙的内存溢出.却发现无法用jcmd连接jvm获取dump.现象: [root@host-12.131.14.15 bin]# ./jcmd 19652 GC.heap_dump  19652: com.sun.tools.attach.AttachNotSupportedException: Unable to...

使用 grep 的 -o 和 -E 选项进行正则的精确匹配

sed 命令可以很好的进行行匹配,但从某一行中精确匹配某些内容,则使用 grep 命令并辅以 -o 和 -E 选项可达到此目的。其中 -o 表示“only-matching”,即“仅匹配”之意。光用它不够,配合 -E 选项使用扩展正则表达式则威力巨大。比如下面有一条文本 tmp.txt ,其中内容为: {"aid":45,"path":"attachmen...

SQLPLUS工具简介

1。 连接 database 远程连接,1)sqlplus /nolog –> conn hanaro@htnsdb –> 输入密码         2)sqlplus hanaro@htnsdb –> 输入密码 本地连接,1)使用本地管理员权限 sqlplus /nolog –> conn /as sysdba 不需要输入密码直...

文件权限及chmod使用方法

文件权限 在linux在,由于安全控制需要,对于不同的文件有不现的权限,限制不同用户的操作权限,总共有rwxXst这一些权限,我们经常使用到的是rwx,对于文件和文件夹而言,他们代表着不同的含义 对于文件 r:用户可以读取该文件,如使用命令cat w:用户可以编辑该文件,如使用命令sed -i,vi x:用户可以运行该文件,如直接./ge...

Linux(centos)新建,删除,移动,重命名文件夹和文件的命令

1.新建文件夹 mkdir 文件名 新建一个名为test的文件夹在home下 view source1 mkdir /home/test 2.新建文本 在home下新建一个test.sh脚本  vi /home/test.sh 3.删除文件或文件夹 1、删除home目录下的test目录  rm /home/test 2、这种不带参数的删除方法经常会提示无法...

ios7 以后准确获取iphone设备的MAC(物理地址)

通过参考 钉钉 项目,知道是通过wifi拿到路由的MAC地址。那么可不可以拿到iphone 设备的MAC 地址呢? 经过一番搜索,发现所有文章都是针对 ios 7 以前 可以拿到。 而且方法也都是同一篇文章上面的,对于ios7 以后完全没提示。 而使用网络上的方法,在 大于 ios 7 的环境下, 永远返回的MAC 为02:00:00:00:00:00 下...