POJ2186 Popular Cows (Tarjan)

题目链接:http://poj.org/problem?id=2186


题解:强连通分量缩点,Your task is to compute the number of cows that are considered popular by every other cow. 只需计算出度为0的点数,如果出度为0的点数大于一,输出0(不符合题意),否则输出出度为0的强连通分量的点数。



#include <stdio.h>          
#include <string.h>   
#define MAXN 10001 

struct node          
{          
	int to,next;   
}edge[50001];      

int belong[MAXN],num[MAXN],outdegree[MAXN];          
int head[MAXN],instack[MAXN],low[MAXN],dfn[MAXN];            
int stack[MAXN],tot,Dindex,top,Bcnt,n;      

void Init()            
{//初始化     
	int i;    
	tot=0,top=0,Dindex=0,Bcnt=0;            
	memset(head,-1,sizeof(head));            
	memset(instack,0,sizeof(instack));            
	memset(dfn,0,sizeof(dfn));            
	memset(low,0,sizeof(low));           
	memset(belong,0,sizeof(belong));    
	memset(num,0,sizeof(num));  
//	memset(indegree,0,sizeof(indegree));  
	memset(outdegree,0,sizeof(outdegree));   
}   

void addEdge(int from,int to)            
{          
	edge[tot].to=to;  
	edge[tot].next=head[from];            
	head[from]=tot++;            
}     

int Scan()                    
{                    
	char ch;                    
	int ret=0;                    
	while((ch=getchar())<'0'||ch>'9');                    
	while(ch>='0'&&ch<='9')                    
	{                    
		ret=ret*10+(ch-'0');                    
		ch=getchar();                    
	}                    
	return ret;                    
}   

void Tarjan(int x)          
{          
	int i,u,v;          
	dfn[x]=low[x]=++Dindex;//时间戳          
	stack[top++]=x;          
	instack[x]=1;          
	for(i=head[x];i!=-1;i=edge[i].next)          
	{          
		u=edge[i].to;          
		if(!dfn[u])          
		{          
			Tarjan(u);          
			low[x]=low[x]>low[u]?low[u]:low[x];          
		}          
		else if(instack[u]&&low[x]>dfn[u])          
			low[x]=dfn[u];          
	}          
	if(low[x]==dfn[x])          
	{     
		Bcnt++;          
		do           
		{          
			v=stack[--top];          
			instack[v]=0;       
			belong[v]=Bcnt;   
			num[Bcnt]++;//保存该强连通分量的点数  
		} while (v!=x);
	}          
}    

int main()  
{  
	int m,i,j,x; 
	while(scanf("%d %d",&n,&m)!=EOF)  
	{    
		Init();  
		while(m--)  
		{  
			i=Scan();  
			j=Scan();  
			addEdge(i,j);  
		}  
		for(i=1;i<=n;++i)  
		{  
			if(!dfn[i])  
				Tarjan(i);  
		} 
		for(i=1;i<=n;++i)  
		{  
			for(j=head[i];j!=-1;j=edge[j].next)    
			{    
				x=edge[j].to;    
				if(belong[i]!=belong[x]) //不在同一个连通分量的点  
				{    
					outdegree[belong[i]]++;
					//indegree[belong[x]]++;  
				}    
			}   
		}  
		x=0;
		for(i=1;i<=Bcnt;++i)
		{
			if(outdegree[i]==0)
			{
				x++;
				j=i;
			}
		}
		if(x==1)
			printf("%d\n",num[j]);
		else
			printf("0\n");
	}  
	return 0;  
}  



你可能感兴趣的:(POJ2186 Popular Cows (Tarjan))