• bzoj1051 [HAOI2006]受欢迎的牛


    1051: [HAOI2006]受欢迎的牛

    Time Limit: 10 Sec  Memory Limit: 162 MB

    Description

      每一头牛的愿望就是变成一头最受欢迎的牛。现在有N头牛,给你M对整数(A,B),表示牛A认为牛B受欢迎。 这
    种关系是具有传递性的,如果A认为B受欢迎,B认为C受欢迎,那么牛A也认为牛C受欢迎。你的任务是求出有多少头
    牛被所有的牛认为是受欢迎的。

    Input

      第一行两个数N,M。 接下来M行,每行两个数A,B,意思是A认为B是受欢迎的(给出的信息有可能重复,即有可
    能出现多个A,B)

    Output

      一个数,即有多少头牛被所有的牛认为是受欢迎的。

    Sample Input

    3 3
    1 2
    2 1
    2 3

    Sample Output

    1

    HINT

    100%的数据N<=10000,M<=50000
     
    Tip:
      这题还是比较经典的tarjan缩点模板题;
      如果A认为B是受欢迎的,那么连A->B;
      将整个图缩点,变成了一个有向无环图;
      如果缩点后的图中点的出度=0的点数大于2个,则没有答案,没有任何一头奶牛能被所有奶牛认可;
                      1个,则答案即那个强连通分量里的点的数量;
     
    Code
    #include<cstdio>
    #include<algorithm>
    #include<iostream>
    #include<cstring>
    #define MAXN 100008
    using namespace std;
    int n,m,hh[MAXN],head[MAXN],vet[MAXN],next[MAXN],tot,dfn[MAXN],low[MAXN],color[MAXN];
    int tot1,num[MAXN],str[MAXN],cnt,boo[MAXN],top,belong[MAXN],tim;
    
    void add(int x,int y){
        tot++;
        hh[tot]=x;
        next[tot]=head[x];
        head[x]=tot;
        vet[tot]=y;
    }
    
    void tarjan(int u){
        tim++;
        dfn[u]=low[u]=tim;
        boo[u]=color[u]=1;
        str[++top]=u;
        for(int i=head[u];i!=-1;i=next[i]){
            int y=vet[i];
            if(color[y]==0){
                tarjan(y);
                low[u]=min(low[u],low[y]);
            }else{
                if(boo[y])
                    low[u]=min(low[u],dfn[y]);
            }
        }
        color[u]=2;
        if(dfn[u]==low[u]){
            cnt++;
            int v;
            do{
                v=str[top--];
                belong[v]=cnt;
                boo[v]=1;
            }while(v!=u&&top>0);
        }
    }
    
    int main(){
        scanf("%d%d",&n,&m);
        for(int i=1;i<=n;i++)
            head[i]=-1;
        for(int i=1;i<=m;i++){
            int x,y;
            scanf("%d%d",&x,&y);
            add(x,y);
        }
        for(int i=1;i<=n;i++)
            if(!dfn[i]){
                tarjan(i);
            }
        for(int i=1;i<=tot;i++){
            if(belong[hh[i]]!=belong[vet[i]]){
                num[belong[hh[i]]]++;
            }
        }
        int ans=0,flag;
        for(int i=1;i<=cnt;i++){
            if(num[i]==0){
                ans++;
                if(ans>1){
                    printf("0");
                    return 0;
                }
                flag=i;
            }
        }
        if(ans==1){
            int res=0;
            for(int i=1;i<=n;i++)
                if(belong[i]==flag)
                    res++;
            printf("%d",res);
        }else{
            printf("0");
        }
    }
      
  • 相关阅读:
    大的FIbonacci数列_Java求法
    HDU1134_Game of Connections 卡特兰数
    oracle中查询锁表
    SpringBoot之使用Druid连接池以及SQL监控和spring监控
    用vue封装插件并发布到npm
    vue 预览 Excel 表格
    vue + elementUI 表格 底部 合计总数
    springboot项目中实现访问druid内置监控页面
    解决Elementui eltable合计 showsummary不显示,样式混乱问题
    Druid连接池:慢查询监控
  • 原文地址:https://www.cnblogs.com/WQHui/p/7475466.html
Copyright © 2020-2023  润新知