poj 2186 (强连通缩点传递关系)

来源:互联网 发布:2k17樱木花道脸部数据 编辑:程序博客网 时间:2024/03/29 16:28

题意:有N头牛 每一头牛都梦想着成为popular cow,(但这是不可能滴) 有m组仰慕的关系,仰慕有传递性比如说A觉得B

是popular and B thinks C is popular, then A thinks C is popalur also;

现在问有多少头牛是会被其他牛都仰慕。

思路:求强连通分量,缩成点 点内的头当然是相互仰慕的咯!! 然后求新的图 的出度 出度也0的点就会被所有牛仰慕算出出度为0的强连通分量里点的个数就OK了,注意 可能有多个出度为0的点,这时输出0 ;


#include<cstdio>#include<cstring>#include<map>#include<vector>#include<cmath>#include<cstdlib>#include<queue>#include <iomanip>#include<iostream>#include<algorithm>using namespace std ;const  int N= 11111 ;const  int M= 55555 ; struct node { int u ,v,next; }edge[M] ; int head[N],low[N],dfn[N],vist[N],stack[N],belong[N],out[N] ; int top ,sum,cnt,dep ;  void add(int u ,int v) {   edge[top].u=u;   edge[top].v=v;   edge[top].next=head[u];   head[u]=top++; }  void tarjan(int u ) {     low[u]=dfn[u]=++dep;     stack[cnt++]=u;     vist[u]=1;     for(int i = head[u] ; i!=-1 ; i=edge[i].next)     {           int  v= edge[i].v ;   if(!dfn[v])   {         tarjan(v) ;         low[u] = min(  low[u] , low[v] ) ;    }else if(vist[v])     low[u] = min(  low[u] , dfn[v] );      } if(low[u] == dfn[u]) {   int x;   sum++ ;   do   {       x=stack[--cnt] ; vist[x] = 0 ;belong[x]=sum;       }while(x!=u) ; } }   int main() { int n,m,u,v ; while(~scanf("%d%d",&n,&m)) {    top  = sum = dep = cnt = 0;    memset(head,-1,sizeof(head));    memset(out,0,sizeof(out));    memset(belong,0,sizeof(belong));    memset(low,0,sizeof(low)) ;    memset(dfn,0,sizeof(dfn)) ;    memset(vist,0,sizeof(vist)) ;    for(int i = 1 ; i <= m ; i++)    {      scanf("%d%d",&u,&v) ;      add(u,v);    }    for(int i = 1 ; i <= n ; i++)        if(!dfn[i])           tarjan(i) ; //  printf("%d*  ",sum);   for(int i = 1 ; i <= n ; i++)     for(int j = head[i] ; j!=-1; j=edge[j].next) {        int  v = edge[j].v ;        if(belong[i] != belong[v])        {            out[belong[i]]++;        } }   int flag = 0 , k ; for(int i = 1 ; i <= sum ; i++)      if(out[i] == 0  )  {     k=i ;     flag++;   if(flag > 1)     break ;     }       if( flag > 1 )    {        printf("0\n");    }    else     {          int ans = 0 ;          for(int i = 1 ; i <= n ; i++)             if(belong[i] == k)                  ans++;           printf("%d\n",ans);           } } return 0; }


0 0
原创粉丝点击