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 2~M+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
n−1次,那些点就是其他的牛都喜欢的牛。最后,我们只要输出这样的点的数量,就可以了。
代码
#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;
}