标签:tarjan
//n个奶牛,
//A B 表示A认为B出名,而且其有传递性
//如A认为B出名,B认为C出名,那么A认为C出名
//问有多少头奶牛所有的奶牛都认为其出名
//先对这个图缩点,记录每一个缩点的个数,然后找出度为0有且只有一个点
//如果是,那么那个点缩了几个点就是答案
#include<cstdio>
#include<cstring>
#include<iostream>
#include<vector>
using namespace std ;
const int maxn = 100010 ;
int dfn[maxn] , low[maxn] , stack[maxn] ;
int isstack[maxn] , head[maxn] ;int vis[maxn] ;
int belong[maxn] , sum[maxn] , ans[maxn] ;
int step , num , top ;
vector<int> vec[maxn] ;
int n , m ;
void init()
{
for(int i = 0;i <= n;i++)
vec[i].clear() ;
step = num = top = 0 ;
memset(dfn , 0 , sizeof(dfn)) ;
memset(vis ,0 , sizeof(vis)) ;
memset(isstack , 0 , sizeof(isstack)) ;
memset(sum , 0 , sizeof(sum)) ;
memset(ans , 0 , sizeof(ans)) ;
}
void tarjan(int u)
{
isstack[u] = 1;
stack[++top] = u ;
low[u] = dfn[u] = ++step ;
for(int i = 0;i < vec[u].size() ; i++)
{
int v = vec[u][i] ;
if(!dfn[v])
{
tarjan(v) ;
low[u] = min(low[u] , low[v]) ;
}
else if(isstack[v])
low[u] = min(low[u] , dfn[v]) ;
}
if(low[u] == dfn[u])
{
num++ ;
int v = 0 ;
while(u != v)
{
v = stack[top--] ;
belong[v] = num ;
ans[num]++ ;
isstack[v] = 0 ;
}
}
}
int main()
{
while(~scanf("%d%d" , &n , &m))
{
init() ;
int u , v ;
for(int i = 1;i <= m;i++)
{
scanf("%d%d" , &u , &v) ;
vec[u].push_back(v) ;
}
for(int i = 1;i <= n;i++)
if(!dfn[i])
tarjan(i);
int flag = 0 ;
for(int i = 1;i <= n;i++)
for(int j = 0 ; j < vec[i].size() ;j++)
{
int v = belong[vec[i][j]] ;
int u = belong[i] ;
if(v == u)continue ;
vis[u] = 1 ;
}
int pos ;
for(int i = 1;i <= num;i++)
if(!vis[i])
{
flag++ ;
pos = i ;
}
if(flag == 1)
cout<<ans[pos]<<endl;
else {puts("0");}
}
}
版权声明:本文为博主原创文章,未经博主允许不得转载。
标签:tarjan
原文地址:http://blog.csdn.net/cq_pf/article/details/47375189