您的位置:首页 > 运维架构

poj2186Popular Cows tarjan缩点

2015-08-09 13:11 375 查看
//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");}
    }
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: