• BZOJ 1051: [HAOI2006]受欢迎的牛( tarjan )


    tarjan缩点后, 有且仅有一个出度为0的强连通分量即answer, 否则无解

    --------------------------------------------------------------------------

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<iostream>
    #include<stack>
     
    #define rep( i, n ) for( int i = 0; i < n; ++i )
    #define clr( x, c ) memset( x, c, sizeof( x ) )
    #define Rep( i, n ) for( int i = 1; i <= n; ++i )
     
    using namespace std;
     
    const int maxn = 10000 + 5;
    const int maxm = 50000 + 5;
     
    struct edge {
    int to;
    edge* next;
    };
     
    edge* pt;
    edge* head[ maxn ];
    edge EDGE[ maxm ];
     
    void init() {
    pt = EDGE;
    clr( head, 0 );
    }
     
    void add_edge( int u, int v ) {
    pt -> to = v;
    pt -> next = head[ u ];
    head[ u ] = pt++;
    }
     
    int dfs_clock, scc_cnt;
    int dfn[ maxn ], low[ maxn ], scc[ maxn ];
    stack< int > S;
     
    void tarjan( int x ) {
    dfn[ x ] = low[ x ] = ++dfs_clock;
    S.push( x );
    for( edge* e = head[ x ]; e; e = e -> next ) {
    int to = e -> to;
    if( ! dfn[ to ] ) {
    tarjan( to );
    low[ x ] = min( low[ x ], low[ to ] );
    } else if( ! scc[ to ] ) 
       low[ x ] = min( low[ x ], dfn[ to ] );
    }
    if( low[ x ] == dfn[ x ] ) {
    scc_cnt++;
    for( ; ; ) {
    int o = S.top();
    S.pop();
    scc[ o ] = scc_cnt;
    if( o == x ) break;
    }
    }
    }
     
    void TARJAN( int n ) {
    dfs_clock = scc_cnt = 0;
    clr( dfn, 0 );
    clr( scc, 0 );
    rep( i, n ) if( ! dfn[ i ] ) tarjan( i );
    }
     
    int out[ maxn ];
     
    int main() {
    init();
    int n, m;
    cin >> n >> m;
    while( m-- ) {
    int u, v;
    scanf( "%d%d", &u, &v );
    add_edge( u - 1, v - 1 );
    }
    TARJAN( n );
    clr( out, 0 );
    rep( i, n ) {
    int x = scc[ i ];
    for( edge* e = head[ i ]; e; e = e -> next )
       if( x != scc[ e -> to ] ) out[ x ]++;
       
    }
    int ans = -1, cnt = 0;
    Rep( i, scc_cnt ) if( ! out[ i ] )
       ans = i, cnt++;
       
    if( ans == -1 || cnt > 1 ) printf( "-1 " );
    else {
    cnt = 0;
    rep( i, n ) 
       if( scc[ i ] == ans ) cnt++;
       
    cout << cnt << " ";
    }
    return 0;
    }

      

    --------------------------------------------------------------------------

    1051: [HAOI2006]受欢迎的牛

    Time Limit: 10 Sec  Memory Limit: 162 MB
    Submit: 2712  Solved: 1426
    [Submit][Status][Discuss]

    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

    Source

  • 相关阅读:
    maven surefire入门
    编译原理随笔4(自下而上的语法分析-递归法)
    编译原理随笔3(自上而下的语法分析-推导法)
    编译原理随笔1
    LeetCode刷题笔记-DP算法-取数问题
    算法刷题笔记-stack-四则运算
    LeetCode刷题笔记-递归-反转二叉树
    Beta里程碑总结
    评价cnblogs.com的用户体验
    我们的团队目标
  • 原文地址:https://www.cnblogs.com/JSZX11556/p/4525633.html
Copyright © 2020-2023  润新知