POJ 2186 Popular Cows

POJ 2186 Popular Cows
先求出有向图强连通分量,缩点之后重新构图,新图为一个 有向无环图,如果在这个DAG是只有一个出度为0的点,那么这个点所表示的强连通分量中的所有点都是符合要求的。
一开始使用list来构建邻接表,结果TLE。后来改成用数组模拟,效率较高。
以下是我的代码:
#include < stack >
#include
< cstdio >
#include
< cstring >
using   namespace  std;
const   int  kMaxn( 10007 );

int  n,m,n2,id[kMaxn];
int  first[kMaxn],edge[ 5 * kMaxn],next[ 5 * kMaxn];

int  dfscnt,dfsn[kMaxn],low[kMaxn];
stack
< int >  s;

void  dfs( int  u)
{
    dfsn[u]
= low[u] =++ dfscnt;
    s.push(u);
    
for ( int  i = first[u];i !=- 1 ;i = next[i])
        
if ( ! dfsn[edge[i]])
        {
            dfs(edge[i]);
            low[u]
= min(low[u],low[edge[i]]);
        }
        
else
            low[u]
= min(low[u],dfsn[edge[i]]);
    
if (dfsn[u] == low[u])
    {
        n2
++ ;
        
int  v;
        
do
        {
            v
= s.top();s.pop();
            id[v]
= n2;
        }
while (v != u);
    }
}

bool  Tarjan( int   & num)
{
    n2
= dfscnt = 0 ;
    memset(dfsn,
0 ,kMaxn * sizeof ( int ));
    
for ( int  i = 1 ;i <= n;i ++ )
        
if ( ! dfsn[i])
            dfs(i);

    
int  counter( 0 ),degree[kMaxn];
    
for ( int  i = 1 ;i <= n2;i ++ )
        degree[i]
= 0 ;
    
for ( int  u = 1 ;u <= n;u ++ )
        
for ( int  i = first[u];i !=- 1 ;i = next[i])
            
if (id[u] != id[edge[i]])
                degree[id[u]]
++ ;
    
for ( int  i = 1 ;i <= n2;i ++ )
        
if ( ! degree[i])
        {
            counter
++ ;
            num
= i;
        }
    
return  (counter == 1 );
}

int  main()
{
    
while (scanf( " %d%d " , & n, & m) == 2 )
    {
        memset(first,
- 1 ,kMaxn * sizeof ( int ));
        
for ( int  i = 1 ;i <= m;i ++ )
        {
            
int  u,v;
            scanf(
" %d%d " , & u, & v);
            edge[i]
= v;
            next[i]
= first[u];
            first[u]
= i;
        }

        
int  num;
        
if (Tarjan(num))
        {
            
int  ans( 0 );
            
for ( int  i = 1 ;i <= n;i ++ )
                
if (id[i] == num)
                    ans
++ ;
            printf(
" %d\n " ,ans);
        }
        
else
            printf(
" %d\n " , 0 );
    }

    
return   0 ;
}

你可能感兴趣的:(POJ 2186 Popular Cows)