POPULAR

P O P U L A R POPULAR POPULAR

题目链接:SSL比赛 1407

题目

每头牛都有一个梦想:成为一个群体中最受欢迎的名牛!在一个有 N N N头牛的牛群中,给你 M M M个二元组 ( A , B ) (A,B) (A,B),表示 A A A认为 B B B是受欢迎的。既然受欢迎是可传递的,那么如果 A A A认为 B B B受欢迎, B B B又认为 C C C受欢迎,则 A A A也会认为 C C C是受欢迎的,哪怕这不是十分明确的规定。你的任务是计算被所有其它的牛都喜欢的牛的个数。

输入

第一行,两个数, N N N M M M。第 2 ~ M + 1 2~M+1 2M+1行,每行两个数, A A A B B B,表示 A A A认为 B B B是受欢迎的。

输出

一个数,被其他所有奶牛认为受欢迎的奶牛头数。

样例输入

3 3
1 2
2 1
2 3

样例输出

1

样例解释

3 3 3号奶牛是唯一被所有其他奶牛认为有名的。

数据范围

1 < = N < = 10 , 000 1<=N<=10,000 1<=N<=10,000
1 < = M < = 50 , 000 1<=M<=50,000 1<=M<=50,000

思路

这道题就是一道 d f s dfs dfs
我们用邻接表储存之后,就从每一个点开始 d f s dfs dfs,给每一个它喜欢的点标记。
最后我们看看有多少个点有被标记 n − 1 n-1 n1次,那些点就是其他的牛都喜欢的牛。最后,我们只要输出这样的点的数量,就可以了。

代码

#include<cstdio>
#include<cstring>

using namespace std;

struct note {
	int to, next;
}a[50001];
int n, m, x, y, k, le[50001], count[50001], ans;
bool in[50001];

void dfs(int now) {//dfs
	in[now] = 1;//标记
	for (int i = le[now]; i; i = a[i].next)
		if (!in[a[i].to]) {
			count[a[i].to]++;//记录
			dfs(a[i].to);
		}
		
}

int main() {
	scanf("%d %d", &n, &m);//读入
	for (int i = 1; i <= m; i++) {
		scanf("%d %d", &x, &y);//读入
		a[++k] = (note){y, le[x]}; le[x] = k;//邻接表储存
	}
	
	for (int i = 1; i <= n; i++) {
		memset(in, 0, sizeof(in));//初始化
		dfs(i);//dfs
	}
	
	for (int i = 1; i <= n; i++)
		if (count[i] == n - 1) ans ++;//记录
	printf("%d", ans);//输出
	
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值