zhber
有好多做过的题没写下来,如果我还能记得就补吧
posts - 501,  comments - 17,  trackbacks - 0

 

Description

每一头牛的愿望就是变成一头最受欢迎的牛。现在有N头牛,给你M对整数(A,B),表示牛A认为牛B受欢迎。 这种关系是具有传递性的,如果A认为B受欢迎,B认为C受欢迎,那么牛A也认为牛C受欢迎。你的任务是求出有多少头牛被所有的牛认为是受欢迎的。

Input

第一行两个数N,M。 接下来M行,每行两个数A,B,意思是A认为B是受欢迎的(给出的信息有可能重复,即有可能出现多个A,B)

Output

一个数,即有多少头牛被所有的牛认为是受欢迎的。

Sample Input

3 3
1 2
2 1
2 3

Sample Output

1

 

 

tarjan缩点之后统计出度为0的点的大小,有多个就直接输出0

#include<cstdio>
#define N 10010
#define M 50010
struct edge{
	int to,next;
}e[M];
int n,m;
int head[N];
int pre[N],low[N];
int sccnum[N],have[N];
int cnt,cnt2,cnt3,top;
int zhan[3*N];
int p[N];
inline int min(int a,int b)
{return a<b?a:b;}
inline void ins(int u,int v)
{
	e[++cnt].to=v;
	e[cnt].next=head[u];
	head[u]=cnt;
}
inline void rebuild()
{
	for (int i=1;i<=n;i++)
	  for (int j=head[i];j;j=e[j].next)
	    if (sccnum[i]!=sccnum[e[j].to])
	      p[sccnum[i]]++;
}
inline void dfs(int x)
{
	zhan[++top]=x;
	low[x]=pre[x]=++cnt2;
	for (int i=head[x];i;i=e[i].next)
	{
	  if(!pre[e[i].to])
	  {
	  	dfs(e[i].to);
	  	low[x]=min(low[x],low[e[i].to]);
	  }else if(!sccnum[e[i].to])
	     low[x]=min(low[x],pre[e[i].to]);
	}
	if (pre[x]==low[x])
	{
		cnt3++;
		int p=-1;
		while (p!=x)
		{
			p=zhan[top];
			top--;
			sccnum[p]=cnt3;
			have[cnt3]++;
		}
	}
}
int main()
{
	scanf("%d%d",&n,&m);
	for(int i=1;i<=m;i++)
	  {
	  	int x,y;
	  	scanf("%d%d",&x,&y);
	  	ins(x,y);
	  }
	for (int i=1;i<=n;i++)
	  if (!pre[i]) dfs(i);
	rebuild();
	int tot=0,sav;
	for (int i=1;i<=cnt3;i++)
	  if (!p[i])tot++,sav=i;
	if (tot>1)
	{
		printf("0\n");
		return 0;
	}else printf("%d",have[sav]);
}

  

posted on 2014-09-20 13:05  zhber  阅读(...)  评论(... 编辑 收藏