zoukankan      html  css  js  c++  java
  • bzoj1051 [HAOI2006]受欢迎的牛 tarjan&&缩点

    题目描述

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

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

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

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

    输入格式:

    第一行:两个用空格分开的整数:N和M

    第二行到第M + 1行:每行两个用空格分开的整数:A和B,表示A喜欢B 

    输出格式:

    第一行:单独一个整数,表示明星奶牛的数量

    tarjan缩点以后重新建图,如果只有一个点没有出边,那么输出这个强联通分量的大小,否则就没有明星牛。

    注意 tarjan缩点时记录每条边连着两点的数组应该开的和变数一样大,我开小就wa了一个点。。。

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    using namespace std;
    int n,m,cnt,head[10005],x[100005],y[100005];
    int dfn[10005],low[10005],vis[10005],hav[10005],bel[10005],q[10005];
    struct edge{
        int next,to;
    }e[100005];
    void insert(int u,int v){
        cnt++;
        e[cnt].next=head[u];e[cnt].to=v;
        head[u]=cnt;
    }
    int top,ind,k;
    void tarjan(int x){
        q[++top]=x;
        dfn[x]=low[x]=++ind;
        vis[x]=1;
        for(int i=head[x];i;i=e[i].next){
            int s=e[i].to;
            if(!dfn[s]){
                tarjan(s);
                low[x]=min(low[s],low[x]);
            }
            else if(vis[s]){
                low[x]=min(dfn[s],low[x]);
            }
        }
        int now=0;
        if(dfn[x]==low[x]){
            k++;
            while(now!=x){
                now=q[top];top--;
                vis[now]=0;
                bel[now]=k;
                hav[k]++;
            }
        }
    }
    int ans;
    void work(){
        for(int i=1;i<=k;i++){
            if(!head[i]){
                if(ans){
                    ans=0;
                    return ;
                }
                else ans=hav[i];
            }
        }
    }
    int mx=0;
    int main(){
        scanf("%d%d",&n,&m);
        int u,v,t;
        for(int i=1;i<=m;i++){
            scanf("%d%d",&x[i],&y[i]);
            insert(x[i],y[i]);
        }
        for(int i=1;i<=n;i++){
            if(!dfn[i])tarjan(i);
        }
        cnt=0;
        memset(head,0,sizeof head);
        memset(e,0,sizeof e);
        for(int i=1;i<=m;i++){
            if(bel[x[i]]!=bel[y[i]])insert(bel[x[i]],bel[y[i]]);
        } 
        work();
        printf("%d",ans);
        return 0;
    }
  • 相关阅读:
    ES6:Iterator遍历器
    前端:对BFC的理解
    前端:性能优化之防抖与节流
    ES6新增数据类型Symbol
    ajax和fetch、aixos的区别
    我对js数据类型的理解和深浅(copy)的应用场景
    egg的基本使用
    前端:css3的过渡与动画的基础知识
    Java基础篇之类
    JAVA基础篇之Scanner
  • 原文地址:https://www.cnblogs.com/Elfish/p/8038402.html
Copyright © 2011-2022 走看看