目录:
题目:
题意:
给出m条信息:表示a认为b很受欢迎。 现在让我们求这所有牛之中最受欢迎的牛的数量。
分析:
先跑一遍 taijan t a i j a n (萌新点击学习)算法。那么出度为0的强连通分量代表的就是受其他奶牛欢迎的,但是如果出度为0的强连通分量的个数大于1.那么则无解。因为将至少有两个分量里的奶牛互相不喜欢。所以我们的算法就是如果出度为0的强连通分量的个数是1.那么我们算出这里面点的个数就是最后的答案。
代码:
#include<cstdio>
#include<cstring>
#include<iostream>
#include<cmath>
#include<queue>
#include<algorithm>
#define LL long long
using namespace std;
inline LL read() {
LL d=0,f=1;char s=getchar();
while(s<'0'||s>'9'){if(s=='-')f=-1;s=getchar();}
while(s>='0'&&s<='9'){d=d*10+s-'0';s=getchar();}
return d*f;
}
int head[50001],tot,dfn[10001],low[10001],tf[10001];
struct node{
int next,to;
}t[50001];
void add(int a,int b)
{
t[++tot].next=head[a];
t[tot].to=b;
head[a]=tot;
return;
}
int qlt[10001],z[10001],d=0,bcnt=0,dindex=0;
void tarjian(int i)
{
int j;
dfn[i]=low[i]=++dindex;//初始化
tf[i]=1;//标记
z[++d]=i;//入栈
for (int q=head[i];q;q=t[q].next)//邻接表
{
j=t[q].to;
if(!dfn[j])//如果j未被访问
{
tarjian(j);//继续
if(low[j]<low[i]) low[i]=low[j];
}
else
if(tf[j]&&dfn[j]<low[i]) low[i]=dfn[j];
}
if(dfn[i]==low[i])
{
bcnt++;//连通块数+1
do
{
j=z[d--];//退栈
tf[j]=0;
qlt[j]=bcnt;
}
while(j!=i);
}
return;
}
int max(int x,int y)
{
return x>y? x:y;
}
int main()
{
int a[50001],b[50001];
int n=read(),m=read();
for(int i=1;i<=m;i++)
{
a[i]=read();b[i]=read();
add(a[i],b[i]);//构建邻接矩阵
}
fill(dfn,dfn+10000,0);//初始化
for(int i=1;i<=n;i++)
if(!dfn[i])
tarjian(i);//tarjan算法
int ans=0,cd[10001],l=0,w;
//下面按照小编所分析的去输出,就不做讲解啦
for(int i=1;i<=m;i++)
{
if(qlt[a[i]]!=qlt[b[i]]) cd[qlt[a[i]]]++;
}
for(int i=1;i<=bcnt;i++)
if(cd[i]==0) ans++,w=i;
if(ans!=1) printf("0");
else
{
ans=0;
for(int i=1;i<=n;i++) if(qlt[i]==w) ans++;
printf("%d",ans);
}
return 0;
}