YBT高效进阶3.4.2 洛谷P2341 POJ2186受欢迎的牛Popular Cows

YBT高效进阶3.4.2 洛谷P2341 POJ2186受欢迎的牛Popular Cows

Title

Time Limit: 2000MS
Memory Limit: 65536K

Description

Every cow’s dream is to become the most popular cow in the herd. In a herd of N (1 <= N <= 10,000) cows, you are given up to M (1 <= M <= 50,000) ordered pairs of the form (A, B) that tell you that cow A thinks that cow B is popular. Since popularity is transitive, if A thinks B is popular and B thinks C is popular, then A will also think that C is
popular, even if this is not explicitly specified by an ordered pair in the input. Your task is to compute the number of cows that are considered popular by every other cow.

Input

  • Line 1: Two space-separated integers, N and M
  • Lines 2…1+M: Two space-separated numbers A and B, meaning that A thinks B is popular.

Output

  • Line 1: A single integer that is the number of cows who are considered popular by every other cow.

Sample Input

3 3
1 2
2 1
2 3

Sample Output

1

Hint

Cow 3 is the only cow of high popularity.

翻译

受欢迎的牛

时限: 2000MS
内存限制: 65536K

描述

每个奶牛的梦想都是成为牛群中最受欢迎的奶牛。在N(1 <= N <= 10,000)头牛群中,您最多可获得M(1 <= M <= 50,000)串有序对(A,B),告诉您母牛A认为母牛B很受欢迎。由于流行是传递性的,因此如果A认为B流行并且B认为C流行,那么A也将认为C
流行,即使未在输入中由有序对明确指定它也是如此。您的任务是计算被其他所有奶牛所欢迎的奶牛数量。

输入

*第1行:两个以空格分隔的整数N和M
*第2…1 + M行:两个以空格分隔的数字A和B,表示A认为B很流行。

输出

*第1行:一个整数,表示被其他所有奶牛所欢迎的奶牛数量。

样本输入

3 3 
1 2 
2 1 
2 3

样本输出

1

暗示

母牛3是唯一具有很高知名度的母牛。

思路

缩点,如果出度为0的点唯一,ans=该点原始点数
若出度为0的点有多个,ans=0
缩点用Floyd or Tanjan or Topsort or Kosaraju

CODE

#include<iostream> 
#include<cstdio>
#include<stack>
using namespace std;
int dfn[50010],low[50010],col[50010],s[50010],v[50010],outs[50010],u[50010],e[50010],nxt[50010],head[50010],tot,len,u2[50010],e2[50010],nxt2[50010],head2[50010],cnt;
stack<int>stck;
void Tanjan(int x)
{
	dfn[x]=low[x]=++tot;stck.push(x);
	for(int i=head[x];i;i=nxt[i])
		if(!dfn[e[i]])Tanjan(e[i]),low[x]=min(low[x],low[e[i]]);
		else if(!col[e[i]])low[x]=min(low[x],dfn[e[i]]);
	if(dfn[x]==low[x])
	{
		for(col[x]=++len,s[len]=1;stck.top()!=x;stck.top(),stck.pop())col[stck.top()]=len,s[len]++;
		stck.pop();
	}
	return;
}
int main() 
{
	ios::sync_with_stdio(false);
	int n,m,i,ans;
	for(cin>>n>>m,i=1;i<=m;i++)
		cin>>u[i]>>e[i],nxt[i]=head[u[i]],head[u[i]]=i;
	for(i=1;i<=n;i++)if(!dfn[i])Tanjan(i);
	for(i=1;i<=m;i++)
		if(col[u[i]]!=col[e[i]])
			u2[++cnt]=col[u[i]],e2[cnt]=col[v[i]],nxt2[cnt]=head2[col[u[i]]],head2[col[u[i]]]=cnt,outs[col[u[i]]]=1;
	for(ans=0,i=1;i<=len;i++)
		if(!outs[i])
		{
			if(ans){cout<<0;return 0;}
			ans=s[i];
		}
	cout<<ans;
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值