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

    题意:

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

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

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

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

    个人认为,tarjan算法鼻祖题

    今天复习了一遍,打了一遍

    dfn即dfs的顺序

    low记录的是能返回到最早遍历的祖先的dfn

    缩点搞搞出度就行了

    若有两个以上的点出度为0

    无解。。。

    #include<cstdio>
    #include<iostream>
    #include<algorithm>
    using namespace std;
    #define love_nmr 0
    #define nmr 50505
    #define olinr 10101
    int n,m;
    int dfn[olinr];
    int low[olinr];
    int ins[olinr];
    int num;
    int du[olinr];
    int cnt;
    int siz[olinr];
    int head[olinr];
    int tot;
    int belong[olinr];
    struct node
    {
        int to,nxt;
    }edge[nmr];
    struct sta
    {
        int ss[olinr];
        int tp;
        void pop()
        {
            tp--;
        }
        int top()
        {
            return ss[tp];
        }
        void push(int x)
        {
            tp++;
            ss[tp]=x;
        }
        bool empty()
        {
            if(!tp) return true;
            return false;
        }
    }s;
    inline int read()
    {
        char ch=getchar();
        int f=1,x=0;
        while(!isdigit(ch))
        {
            if(ch=='-')
                f=-f;
            ch=getchar();
        }
        while(isdigit(ch))
        {
            x=(x<<1)+(x<<3)+(ch^48);
            ch=getchar();
        }
        return x*f;
    }
    inline void put(int x)
    {
        if(x<0)
        {
            putchar('-');
            x=-x;
        }
        if(x>9)
            put(x/10);
        putchar(x%10+'0');
    }
    inline void tarjan(int x)
    {
        s.push(x);
        ins[x]=true;
        dfn[x]=low[x]=++tot;
        for(int i=head[x];i;i=edge[i].nxt)
        {
            int go=edge[i].to;
            if(!dfn[go])
            {
                tarjan(go);
                low[x]=min(low[x],low[go]);
            }
            else if(ins[go])
                low[x]=min(low[x],dfn[go]);
        }
        if(dfn[x]==low[x])
        {
            int tp=0;
            num++;
            do
            {
                tp=s.top();
                s.pop();
                ins[tp]=false;
                belong[tp]=num;
                siz[num]++;
            }while(tp!=x);
        }
    }
    inline void add(int from,int to)
    {
        cnt++;
        edge[cnt].to=to;
        edge[cnt].nxt=head[from];
        head[from]=cnt;
    }
    int main()
    {
        n=read();
        m=read();
        int x,y;
        for(int i=1;i<=m;i++)
        {
            x=read();
            y=read();
            add(x,y);
        }    
        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=edge[j].nxt)
            {
                int go=edge[j].to;
                if(belong[go]!=belong[i])
                {
                    du[belong[i]]++;
                }
            }
        int ans=0;
        for(int i=1;i<=num;i++)
        {
            if(!du[i])
            {
                if(ans)
                {
                    put(0);
                    return 0;
                }
                ans=siz[i];
            }
        }
        put(ans);
        return 0;
    }
  • 相关阅读:
    ReentrantLock的实现语义与使用场景
    队列同步器详解
    设计模式--模板方法模式
    Synchronized及其实现原理
    JAVA线程基础
    JAVA内存模型
    java 线上问题定位工具
    JMX超详细解读
    Hexo
    [转]html5 video在安卓大部分浏览器包括微信最顶层的问题
  • 原文地址:https://www.cnblogs.com/olinr/p/9444331.html
Copyright © 2011-2022 走看看