和hdu的3639有点相似,不过最后求的不太一样。。

方法还是一样的,我也是用强连通分量+反向图做的。。

有一周没写强连通了,,有点手生了,以后要多练习练习。。

题目大意:有N头牛 ,如果a 牛喜欢b牛 而 b牛喜欢c牛,那a和b都喜欢c牛。。

像那种爱屋及乌。。也就是喜欢是可以传递的,问最后 被除它自己之外的所有牛  都喜欢的牛 的数量。。

有那么一点拗口。。。

先用强连通缩点,, 之后建立反向图,,从入度为0的开始深搜,,

如果该点符合条件的话 就加上该点的权值(即是该点所包含的牛的数量),之后输出即可。。。

# include<stdio.h>
# include<string.h>
# define N 10005
# define M 50005
struct node{
	int from,to,next;
}edge1[M],edge2[M],edge[M];
int head1[N],head2[N],head[N],Belong[N],in[N];
int visit1[N],visit2[N],visit[N],val[N],T[N];
int Bcnt,Tcnt,tol,tol1,tol2,count;
void add(int a,int b)
{
	edge1[tol1].from=a;edge1[tol1].to=b;edge1[tol1].next=head1[a];head1[a]=tol1++;
	edge2[tol2].from=b;edge2[tol2].to=a;edge2[tol2].next=head2[b];head2[b]=tol2++;
}
void add1(int a,int b)
{
	edge[tol].from=a;edge[tol].to=b;edge[tol].next=head[a];head[a]=tol++;
}
void dfs1(int x)
{
	int j;
	visit1[x]=1;
	for(j=head1[x];j!=-1;j=edge1[j].next)
		if(visit1[edge1[j].to]==0) dfs1(edge1[j].to);
		T[Tcnt++]=x;
}
void dfs2(int x)
{
	int j;
	Belong[x]=Bcnt;
	count++;
	visit2[x]=1;
	for(j=head2[x];j!=-1;j=edge2[j].next)
		if(visit2[edge2[j].to]==0) dfs2(edge2[j].to);
}
void dfs(int x)
{
	int i;
	visit[x]=1;
	count++;
	for(i=head[x];i!=-1;i=edge[i].next)
		if(visit[edge[i].to]==0) dfs(edge[i].to);
}
int main()
{
	int i,a,b,index,n,m,x,y;
	scanf("%d%d",&n,&m);
	Tcnt=0;
	Bcnt=0;//表示强连通分量的个数
	tol1=0;
	tol2=0;
	for(i=0;i<=n;i++)
	{
		head1[i]=-1;
		head2[i]=-1;
		visit1[i]=0;
		visit2[i]=0;
	}
	for(i=1;i<=m;i++)
	{
		scanf("%d%d",&a,&b);
		add(a,b);
	}
	for(i=1;i<=n;i++)
		if(visit1[i]==0) dfs1(i);
		for(i=Tcnt-1;i>=0;i--)
		{
			if(visit2[T[i]]==0) 
			{
				count=0;
				dfs2(T[i]);
				val[Bcnt]=count;
				Bcnt++;
			}
		}
		for(i=0;i<Bcnt;i++)
		{
			in[i]=0;
			head[i]=-1;
		}
		for(i=0;i<tol1;i++)
		{
			x=Belong[edge1[i].from];
			y=Belong[edge1[i].to];
			if(x!=y)
			{
				in[x]++;
				add1(y,x);
			}
		}
		index=0;
		for(i=0;i<Bcnt;i++)
		{
			if(in[i]==0)
			{
				memset(visit,0,sizeof(visit));
				count=0;
				dfs(i);
				if(count==Bcnt) {index+=val[i];} 
			}
		}
		printf("%d\n",index);
	return 0;
}
posted on 2011-05-06 22:36  奋斗青春  阅读(260)  评论(0编辑  收藏  举报