POJ 2186


const int maxn = 10008 ;
const int maxm = 50008 ;

struct E{
       int v , next ;
}e[maxm] ;

int eid , g[maxn] ;
void add(int u , int v){
     e[eid].v = v ;
     e[eid].next = g[u] ;
     g[u] = eid++ ;
}

//---------------
int   low[maxn] , dfn[maxn] , dfntime ;
int   _stack[maxn] , top ;
bool  _instak[maxn] ;
//--------------
int   belong[maxn] , bcc , bccsum[maxn] ;

void tarjan(int u){
     low[u] = dfn[u] = ++dfntime ;
     _stack[++top] = u ;
     _instak[u] = 1 ;
     for(int i = g[u] ; i != -1 ; i = e[i].next){
           int v = e[i].v ;
           if(! dfn[v]){
               tarjan(v) ;
               low[u] = min(low[u] , low[v]) ;
           }
           else if(_instak[v])  low[u] = min(low[u] , dfn[v]) ;
     }
     if(low[u] == dfn[u]){
          bcc++ ;
          int v  ;
          do{
              v = _stack[top--] ;
              _instak[v] = 0 ;
              belong[v] = bcc ;
              bccsum[bcc]++ ;
          }while(v != u) ;
     }
}

void inittarjan(){
     dfntime = 0 ;
     eid = 0 ;
     memset(g , -1 , sizeof(g)) ;
     memset(dfn , 0 , sizeof(dfn)) ;
     memset(low , 0 , sizeof(low)) ;
     memset(_instak , 0 , sizeof(_instak)) ;
     top = 0 ;
     bcc = 0 ;
     memset(bccsum , 0 , sizeof(bccsum)) ;
}


int dg[maxn] ;

int main(){
    int n , m , u , v ;
    while(scanf("%d%d" , &n , &m) != EOF){
         inittarjan() ;
         while(m--){
              scanf("%d%d" , &u , &v) ;
              add(u , v) ;
         }

         for(int i = 1 ; i <= n ; i++){
              if(! dfn[i]) tarjan(i) ;
         }
         memset(dg , 0 , sizeof(dg)) ;
         for(int u = 1 ; u <= n ; u++){
              for(int i = g[u] ; i != -1 ; i = e[i].next){
                   int v = e[i].v ;
                   int bu = belong[u] ;
                   int bv = belong[v] ;
                   if(bu != bv) dg[bu]++ ;
              }
         }
         int _sum = 0 ;
         for(int i = 1 ; i <= bcc ; i++){
               if(dg[i] == 0){
                    _sum++ ;
                    u = i ;
               }
         }
         if(_sum == 1) printf("%d\n" , bccsum[u]) ;
         else   printf("0\n") ;
    }
    return 0 ;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值