1051: [HAOI2006]受欢迎的牛

题目:http://www.lydsy.com/JudgeOnline/problem.php?id=1051

tarjan求强连通分量,之后判断出度为0的分量个数。
若不为1,答案是0;若为1,答案是出度为0的强连通分量的包含节点个数。
#include <iostream>
#include 
<cstring>
#include 
<cstdlib>
#include 
<cstdio>
#include 
<algorithm>
using namespace std;
const int MaxN=10001;
const int MaxM=50001;

int n,m,a[MaxM][2];
int head[MaxN],node[MaxM],next[MaxM],t=0;
int belong[MaxN],size[MaxN];
bool in[MaxN];
int stack[MaxN],DFN[MaxN],Low[MaxN],Index=0,top=-1,vis[MaxN],tot=1;

void add(int x,int y)
{
    node[t]
=y;
    next[t]
=head[x];
    head[x]
=t;
    t
++;
}


void init()
{
    memset(head,
-1,sizeof(head));
    memset(next,
-1,sizeof(next));
    memset(vis,
0,sizeof(vis));
    memset(
in,0,sizeof(in));
    cin
>>n>>m;
    
for (int i=0;i<m;i++)
    
{
        cin
>>a[i][0]>>a[i][1];
        add(a[i][
0],a[i][1]);
    }

}


void tarjan(int u)
{
    DFN[u]
=Low[u]=++Index;
    stack[
++top]=u;
    vis[u]
=1;
    
for (int i=head[u];i!=-1;i=next[i])
    
{
        
if (vis[node[i]]==0)
        
{
            tarjan(node[i]);
            Low[u]
=min(Low[u],Low[node[i]]);
        }

        
else
        
{
            
if (vis[node[i]]==1)
            
{
                Low[u]
=min(Low[u],DFN[node[i]]);
            }

        }

    }

    
if (DFN[u]==Low[u])
    
{
        
//cout<<tot<<':';
        for (;stack[top]!=u;)
        
{
            
//cout<<stack[top]<<' ';
            vis[stack[top]]=2;
            belong[stack[top
--]]=tot;
            size[tot]
++;
        }

        
//cout<<stack[top]<<endl;
        vis[stack[top]]=2;
        belong[stack[top
--]]=tot;
        size[tot]
++;
        
//cout<<size[tot]<<endl;
        tot++;
    }

}


int main()
{
    init();
    
for (int i=1;i<=n;i++)
    
{
        
if (vis[i]==0)
        
{
            tarjan(i);
        }

    }

    
int ans=tot-1;
    
for (int i=0;i<m;i++)
    
{
        
if (belong[a[i][0]]!=belong[a[i][1]] && in[belong[a[i][0]]]==0)
        
{
            
in[belong[a[i][0]]]=1;
            ans
--;
        }

    }

    
//cout<<ans<<endl;
    if (ans!=1)
    
{
        cout
<<0<<endl;
        
return 0;
    }

    
for (int i=1;i<=tot;i++)
    
{
        
if (in[i]==0)
        
{
            cout
<<size[i]<<endl;
            
return 0;
        }

    }

    
return 0;
}


posted on 2013-02-14 21:45 Kiro 阅读(158) 评论(0)  编辑 收藏 引用 所属分类: 衡八oj