zoukankan      html  css  js  c++  java
  • 受欢迎的奶牛-洛谷2341

    咕咕咕

    (可能是寒假集训时就留的题吧,结果被我咕到了现在...

    tarjan的简单应用,这还是很简单看出来。

    那么明星奶牛是 图中唯一一个出度为0的强联通分量。

    如果存在两个或者两个以上的出度为0的强联通分量,则不存在明星奶牛,因为这几个出度为0的强连通分量之间无法传递“爱慕”

    所以,最终答案就是强联通分量中的奶牛个数!

    #include<cstdio>
    #include<algorithm>
    #include<queue> 
    #include<stack>
    #define ll long long
    using namespace std;
    
    inline ll read()
    {
        ll sum = 0, p = 1;
        char ch = getchar();
        while(ch < '0' || ch > '9')
        {
            if(ch == '-')
                p = -1;
            ch = getchar();
        }
        while(ch >= '0' && ch <= '9')
        {
            (sum *= 10) += ch - '0';
            ch = getchar();
        }
        return sum * p;
    }
    
    const int maxn = 10005,maxm = 50005;
    struct edge
    {
        int nxt,to;
    }e[maxm];
    int n,m,cnt,tot,ncnt;
    int dfn[maxn],low[maxn],mrk[maxn],id[maxn],du[maxn],head[maxn];
    bool vis[maxn];
    stack<int> q;
    
    void add(int a,int b)
    {
        e[++cnt].to = b;
        e[cnt].nxt = head[a];
        head[a] = cnt;
    }
    
    void tarjan(int x)
    {
        dfn[x] = low[x] = ++tot;
        q.push(x);
        vis[x] = true;
        for(int i = head[x];i;i = e[i].nxt)
        {
            int v = e[i].to;
            if(!dfn[v])
            {
                tarjan(v);
                low[x] = min(low[x],low[v]);
            }
            else if(vis[v])
                low[x] = min(low[x],dfn[v]);
        }
        int k;
        if(dfn[x] == low[x])
        {
            ncnt++;
            do
            {
                k = q.top();
                q.pop();
                vis[k] = false;
                id[k] = ncnt;
                mrk[ncnt]++;
            }while(x != k); 
        }
    }
    
    int main()
    {
        n = read(),m = read();
        for(int i = 1;i <= m;i++)
        {
            int a = read(),b = read();
            add(a,b);
        }
        for(int i = 1;i <= n;i++)
            if(!dfn[i])
                tarjan(i);
        for(int i = 1;i <= n;i++)
            for(int j = head[i];j;j = e[j].nxt)
            {
                int v = e[j].to;
                if(id[i] != id[v])
                    du[id[i]]++;
            }
        int ans = 0;
        for(int i = 1;i <= ncnt;i++)
        if(!du[i])
        {
            if(ans)
            {
                printf("0
    ");
                return 0;
            }
            ans = i;
        }
        printf("%d
    ",mrk[ans]);
        return 0;
    }
  • 相关阅读:
    mysql相关
    java注解@Valid@Validated表单验证
    驼峰参数、下划线["_"]参数,属性互传
    redis,windows设置记录
    Java入门第一季学习总结
    计算属性calc()的运算规则
    swiper实现翻页,页面高度超出可滚动
    git常用命令
    Linux下svn常用命令
    图片高度不够一页,如何覆盖全屏
  • 原文地址:https://www.cnblogs.com/darlingroot/p/11228559.html
Copyright © 2011-2022 走看看