BZOJ 1051-受欢迎的牛(强连通)

1051: [HAOI2006]受欢迎的牛

Time Limit: 10 Sec   Memory Limit: 162 MB
Submit: 5537   Solved: 2940
[ Submit][ Status][ Discuss]

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

HINT

100%的数据N<=10000,M<=50000

Source


强连通模板题   ->自己整理的tarjan模板


会强连通的话,很容易想到,牛A喜欢牛B的话,呢就在他们之间建一条有向边,

若当前的牛被其他所有牛喜欢的话,则当前牛所在的强连通分量出度必为0,很容易证明的

反之,若存在大于1个强连通分量的出度为0,则一定不存在有牛被其他所有牛喜欢


#include<stack>
#include<vector>
#include <stdio.h>
#include <string.h>
#include <algorithm>
using namespace std;
#define maxn 1000005
stack<int>s;
vector<int>q[maxn],p[maxn];
int dfn[maxn],low[maxn],t,cnt,vis[maxn],in[maxn],num,ans[maxn],belong[maxn];
void tarjan(int u)
{
	int i,now;
	dfn[u]=low[u]=++t;
	s.push(u);in[u]=1;vis[u]=1;
	for(i=0;i<q[u].size();i++)
	{
		int v=q[u][i];
		if(vis[v]==0)
		{
			tarjan(v);
			low[u]=min(low[u],low[v]);
			continue;
		}
		if(in[v])
			low[u]=min(low[u],dfn[v]);
	}
	if(dfn[u]==low[u])
	{
		num++;
		int sum=0;
		while(s.empty()==0)
		{
			sum++;
			now=s.top();
			s.pop();
			in[u]=0;
			belong[now]=num;
			if(now==u)
				break;
		}
		ans[num]=sum;
	}
}
int  main(void)
{
	int i,j,x,y,n,m;
	scanf("%d%d",&n,&m);
	for(i=1;i<=m;i++)
	{
		scanf("%d%d",&x,&y);
		q[x].push_back(y);
	}
	for(i=1;i<=n;i++)
		if(vis[i]==0)
			tarjan(i);
	for(i=1;i<=n;i++)
		for(j=0;j<q[i].size();j++)
		{
			int v=q[i][j];
			if(belong[i]!=belong[v])
				p[belong[i]].push_back(belong[v]);
		}
	int sum=0,anss=0;
	for(i=1;i<=num;i++)
		if(p[i].size()==0)
			sum++,anss=ans[i];
	if(sum==1)
		printf("%d\n",anss);
	else
		printf("0\n");
	return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值