• 【洛谷P2341】[HAOI2006]受欢迎的牛


    题目描述

    每头奶牛都梦想成为牛棚里的明星。被所有奶牛喜欢的奶牛就是一头明星奶牛。所有奶

    牛都是自恋狂,每头奶牛总是喜欢自己的。奶牛之间的“喜欢”是可以传递的——如果A喜

    欢B,B喜欢C,那么A也喜欢C。牛栏里共有N 头奶牛,给定一些奶牛之间的爱慕关系,请你

    算出有多少头奶牛可以当明星。

    输入输出格式

    输入格式:

     第一行:两个用空格分开的整数:N和M

     第二行到第M + 1行:每行两个用空格分开的整数:A和B,表示A喜欢B

    输出格式:

     第一行:单独一个整数,表示明星奶牛的数量

    输入输出样例

    输入样例#1:
    3 3
    1 2
    2 1
    2 3
    输出样例#1:
    1

    说明

    只有 3 号奶牛可以做明星

    【数据范围】

    10%的数据N<=20, M<=50

    30%的数据N<=1000,M<=20000

    70%的数据N<=5000,M<=50000

    100%的数据N<=10000,M<=50000

    分析

    知识点:强连通分量缩点tarjan算法的裸题。

    缩点之后整个图肯定是一颗树,只要找到出度为零的那个缩点里所包含点的个数就行了。

    如果出度>1,是肯定没有答案的。

    为什么是>1,因为当=0时,也就是整个图都在一个连通分量中,此时所有点都是可以的。

    数组尽量开大一点,因为A,B的范围并没有给,如果A,B太大的话就要用到离散化。

    代码

    #include<iostream>
    #include<cstring>
    #include<cstdio>
    #include<algorithm>
    using namespace std;
    const int maxn=100000+5;
    inline int read()
    {
        int x=0,f=1; char ch=getchar();
        while(ch<'0'||ch>'9'){if(ch=='-')f=-1; ch=getchar();}
        while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
        return x*f;
    }
    int n,m,tot,idx,top,cnt,ans,k;
    int head[maxn],u[maxn],v[maxn],du[maxn];
    int dfn[maxn],low[maxn],sta[maxn],belong[maxn],num[maxn];
    bool ins[maxn];
    struct node
    {
        int next,to;
    }e[maxn*5];
    inline void add(int from,int to)
    {
        e[++tot].next=head[from];
        e[tot].to=to;
        head[from]=tot;
    }
    void tarjan(int x)
    {
        dfn[x]=low[x]=++idx;
        sta[++top]=x; ins[x]=1;
        for(int i=head[x];i;i=e[i].next)
        {
            int to=e[i].to;
            if(!dfn[to])
            {
                tarjan(to);
                low[x]=min(low[x],low[to]);
            }else if(ins[to])
            low[x]=min(low[x],dfn[to]);
        }
        if(dfn[x]==low[x])
        {
            int y; cnt++;
            do
            {
                y=sta[top--];
                ins[y]=0;
                belong[y]=cnt;
                num[cnt]++;
            }while(x!=y);
        }
    }
    int main()
    {
        n=read();m=read();
        for(int i=1;i<=m;i++)
        {
            u[i]=read();v[i]=read();
            add(u[i],v[i]);
        }
        for(int i=1;i<=n;i++)
        if(!dfn[i]) tarjan(i);
        for(int i=1;i<=m;i++)
        if(belong[u[i]]!=belong[v[i]])
        du[belong[u[i]]]++;
        for(int i=1;i<=cnt;i++)
        if(!du[i]) k++,ans=num[i];
        if(k>1) {printf("%d
    ",0);return 0;}
        printf("%d
    ",ans);
        return 0;
    }
    欢迎转载,转载请注明出处!
  • 相关阅读:
    SQL Service Database BACKUP & RESTORE
    vb.net 写入文件同步锁
    ActiveXObject Word.Application 打印小票
    jquery 计算输入的文本的utf-8字节长度
    sql 随笔 2015-08-07
    Android Calander Event
    Html 全屏切换效果
    C#中ref和out关键字的应用以及区别
    Angular安装、卸载 (高版本会导致component.html页面空白)
    bootstrap导航栏(navbar)下拉框无法展开
  • 原文地址:https://www.cnblogs.com/huihao/p/7624776.html
Copyright © 2020-2023  润新知