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

    题目描述:

    每一头牛的愿望就是变成一头最受欢迎的牛。现在有N头牛,给你M对整数(A,B),表示牛A认为牛B受欢迎。 这
    种关系是具有传递性的,如果A认为B受欢迎,B认为C受欢迎,那么牛A也认为牛C受欢迎。你的任务是求出有多少头
    牛被所有的牛认为是受欢迎的。
     
    题解:
    tarjan缩点。
    由题可得,受欢迎的奶牛只有可能是图中唯一的出度为零的强连通分量中的所有奶牛,
    所以若出现两个以上出度为0的强连通分量则不存在明星奶牛,因为那几个出度为零的分量的爱慕无法传递出去。
    那唯一的分量能受到其他分量的爱慕同时在分量内相互传递,所以该分量中的所有奶牛都是明星。
    附上代码:
    #include<cstdio> 
    #include<cstring>  
    int idx,ans2,low[50001],deep[50001],idx2,cnt,last[50001],x[50001],y[50001],z[50001],top,f[50001],ans[50001],num[50001],n,m;  
    bool inz[50001]; 
    struct edge
    {
        int to,next;
    }e[50001];  
    int min(int a,int b)  
    {  
        if(a<b)
            return a;  
        return b;
    }  
    void addage(int x,int y)  
    {  
         e[++idx].to=y; 
         e[idx].next=last[x]; 
         last[x]=idx;  
    }   
    void tarjan(int x)  
    {  
        low[x]=deep[x]=++cnt;  
        z[++top]=x;   
        inz[x]=1;   
        for(int i=last[x];i>=0;i=e[i].next) 
        {  
            if(!deep[e[i].to])  
             {  
                tarjan(e[i].to);  
                low[x]=min(low[x],low[e[i].to]);  
              }  
            else if(inz[e[i].to]&&low[x]>deep[e[i].to]) 
                  low[x]=deep[e[i].to];   
        }   
        if(low[x]==deep[x])  
         {  
            idx2++;
            int t=-1;  
            while(x!=t)
            {  
                t=z[top--];  
                ans[idx2]++;  
                f[t]=idx2;  
                inz[t]=0;  
            } 
         }    
    }   
    int main()  
    {   
        scanf("%d%d",&n,&m); 
        memset(last,-1,sizeof(last)); 
        for(int i=1;i<=m;i++)  
        {  
            scanf("%d%d",&x[i],&y[i]);  
            addage(x[i],y[i]);  
        }
        for(int i=1;i<=n;i++)  
             if(!deep[i]) 
                 tarjan(i);    
        for(int i=1;i<=m;i++)  
             if(f[x[i]]!=f[y[i]])  
                   num[f[x[i]]]++;   
        for(int i=1;i<=idx2;i++)  
          if(!num[i])  
           {  
                if(ans2)  
                {
                    printf("0"); 
                    return 0;
                }  
                ans2=i;  
           }  
        printf("%d",ans[ans2]);   
    }
  • 相关阅读:
    第二次结对编程作业
    第一次结对编程作业
    团队项目需求分析报告
    第03组 团队Git现场编程实战
    团队项目选题报告
    上传大文件的问题
    Maven安装与环境变量设置
    jsp中的相对路径和绝对路径
    Highcharts使用入门随笔
    Tomcat服务器项目外网无法访问
  • 原文地址:https://www.cnblogs.com/jiangminghong/p/9816645.html
Copyright © 2011-2022 走看看