zoukankan      html  css  js  c++  java
  • [HAOI2006]受欢迎的牛

    [HAOI2006]受欢迎的牛

     
     洛谷P2341
    https://www.luogu.org/problemnew/show/P2341
    JDOJ 1076
    https://neooj.com/oldoj/problem.php?id=1076

    题目描述

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

    牛都是自恋狂,每头奶牛总是喜欢自己的。奶牛之间的“喜欢”是可以传递的——如果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求强连通分量,然后缩点,由题可得,受欢迎的奶牛只有可能是图中唯一的出度为零的强连通分量中的所有奶牛,所以若出现两个以上出度为0的强连通分量则不存在明星奶牛,因为那几个出度为零的分量的爱慕无法传递出去。那唯一的分量能受到其他分量的爱慕同时在分量内相互传递,所以该分量中的所有奶牛都是明星。

    AC代码

    #include<cstdio>
    #include<algorithm>
    using namespace std;
    int n,m;
    int tot,to[50001],nxt[50001],head[10001];
    int z[10001],inz[10001],deep[10001],low[10001],v[10001],cnt,ans,top,belong[10001];
    int chudu[10001];
    int f[10001];
    void add(int x,int y)
    {
        to[++tot]=y;
        nxt[tot]=head[x];
        head[x]=tot;
    }
    void tarjan(int x)
    {
        z[++top]=x;
        v[x]=1;
        inz[x]=1;
        deep[x]=low[x]=++cnt;
        for(int i=head[x];i;i=nxt[i])
        {
            int y=to[i];
            if(v[y]==0)
                tarjan(y),low[x]=min(low[x],low[y]);
            else if(inz[y]==1)
                low[x]=min(low[x],deep[y]);
        }
        if(deep[x]==low[x])
        {
            ans++;
            int t;
            do
            {
                t=z[top--];
                inz[t]=0;
                belong[t]=ans;
                f[ans]++;
            }while(t!=x);
        }
    }
    int main()
    {
        scanf("%d%d",&n,&m);
        for(int i=1;i<=m;i++)
        {
            int a,b;
            scanf("%d%d",&a,&b);
            add(a,b);
        }
        for(int i=1;i<=n;i++)
            if(v[i]==0)
                tarjan(i);
        for(int i=1;i<=n;i++)
            for(int j=head[i];j;j=nxt[j])
                if(belong[i]!=belong[to[j]])
                    chudu[belong[i]]++;
        int tt=0;
        for(int i=1;i<=ans;i++)
            if(chudu[i]==0)
            {
                if(tt)
                {
                    printf("0");
                    return 0;
                }
                tt=i;
            }
        printf("%d",f[tt]);
        return 0;
    }
  • 相关阅读:
    java关键字之synchronized
    java多线程之线程安全
    java多线程之管道流
    java多线程之多生产者-多消费者
    java多线程之生产者-消费者
    java多线程之wait和notify
    python读取json文件并解析
    java之继承中的静态变量
    shell多线程(3)while循环
    equals与hashcode
  • 原文地址:https://www.cnblogs.com/fusiwei/p/11162629.html
Copyright © 2011-2022 走看看