题目描述:
DescriptionEvery 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.
(这是不标准的翻译,,为了让我们搜不到,学长改题也算是煞费苦心,大体意思差不多)
在zyh的高中,学生会每一年都会评选受欢迎学生,所谓受欢迎的学生,就是被所有学生喜欢的学生。 每个学生都喜欢自己,碰巧的是,如果学生A
喜欢学生B ,学生B喜欢学生C, 那么学生A也喜欢学生C。 但是学生A喜欢学生B 并不意味着学生B喜欢学生A。
zyh参与了评选工作,苦逼的他被安排去购买奖品,于是他拿到了一张表,这张表有m条记录,每条记录由两个数字a,b组成,表示a,喜欢b
,但是由于学生太多了,他无法知道会有多少个受欢迎的学生,从而无法去购买奖品,你能帮他解决吗?
输入:
第1行:两个以空格分隔的整数,N和M.
第2行到第N+M行:两个以空格分隔的数字A和B,意味着A喜欢B。
1<=N<10,000 , 1 <= M <= 50,000.
输出:
输出一个数-zyh所需购买的奖品数。
样例输入:
3 3
1 2
2 1
2 3
样例输出:
1
强联通分量的模板题目,在
code :
两次dfs进行缩点,详情描述请看这是我们另一篇博客,简单的说了一下这样写的作用
如果真的有这样的人/牛,一定是在搜索的最后一个出现
只需要判断最后一个能不能满足这样的要求即可
#include<stdio.h>
#include<iostream>
#include<string.h>
#include<vector>
#include<stack>
using namespace std;
int v,m;
const int maxn=10050;
vector<int> g[maxn];
vector<int> rg[maxn];
vector<int> vs;
bool used[maxn];
int cmp[maxn];
void add_edge(int from,int to)
{
g[from].push_back(to);
rg[to].push_back(from);
}
void dfs(int v)
{
used[v]=true;
for(int i=0;i<g[v].size();i++)
{
if(!used[g[v][i]])dfs(g[v][i]);
}
vs.push_back(v);
}
void rdfs(int v,int k)
{
used[v]=true;
cmp[v]=k;
for(int i=0;i<rg[v].size();i++)
{
if(!used[rg[v][i]])rdfs(rg[v][i],k);
}
}
int scc()
{
memset(used,0,sizeof(used));
vs.clear();
for(int i=0;i<v;i++)
{
if(!used[i])dfs(i);
}
memset(used,0,sizeof(used));
int k=0;
for(int i=vs.size()-1;i>=0;i--)
{
if(!used[vs[i]])rdfs(vs[i],k++);
}
return k;
}
int main()
{
scanf("%d%d",&v,&m);
int a,b;
for(int i=0;i<m;i++)
{
scanf("%d%d",&a,&b);
add_edge(a-1,b-1);
}
int n=scc();
int u=0,num=0;
for(int i=0;i<v;i++)
{
if(cmp[i]==n-1)
{
u=i;
num++;
}
}
memset(used,0,sizeof(used));
rdfs(u,0);
for(int i=0;i<v;i++)
{
if(!used[i])
{
num=0;
break;
}
}
printf("%d\n",num);
return 0;
}