有n头牛,m个崇拜关系,并且崇拜具有传递性,如果a崇拜b,b崇拜c,则a崇拜c,求最后有几头牛被所有牛崇拜。
Sample Input
3 3
1 2
2 1
2 3
Sample Output
1
显然一个强联通分量内的所有点都是满足条件的,我们可以对整张图进行缩点,然后就简单了。
剩下的所有点都不是强连通的,现在整张图就是一个DAG(有向无环图)
那么就变成一道水题了,因为这是一个有向无环图,不存在所有点的出度都不为零的情况。
所以必然有1个及以上的点出度为零,如果有两个点出度为零,那么这两个点肯定是不相连的,即这两圈牛不是互相崇拜的,于是此时答案为零,如果有1个点出度为0,那么这个点就是被全体牛崇拜的,
这个点可能是一个强联通分量缩成的超级点,所以应该输出整个强联通分量中点的个数。
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=1e4+5;
int dfn[maxn],belong[maxn],low[maxn],vis[maxn],deep,sum;
int cnt[maxn],du[maxn];
int n,m,out,tmp;
vector<int> G[maxn];
stack<int> s;
void tarjan(int u)
{
dfn[u]=low[u]=++deep;
vis[u]=1;
s.push(u);
for(int i=0;i<G[u].size();i++)
{
int v=G[u][i];
if(!dfn[v])
{
tarjan(v);
low[u]=min(low[u],low[v]);
}
else if(vis[v])
{
low[u]=min(low[u],dfn[v]);
}
}
if(dfn[u]==low[u])
{
belong[u]=++sum;
vis[u]=0;
while(s.top()!=u)
{
belong[s.top()]=sum;
vis[s.top()]=0;
s.pop();
}
s.pop();
}
}
int main()
{
scanf("%d%d",&n,&m);
for(int i=0;i<m;i++)
{
int u,v;scanf("%d%d",&u,&v);
G[u].push_back(v);
}
for(int i=1;i<=n;i++)
{
if(!dfn[i]) tarjan(i);
}
for(int i=1;i<=n;i++)
{
for(int j=0;j<G[i].size();j++)
{
if(belong[i]!=belong[G[i][j]]) du[belong[i]]++;
}
cnt[belong[i]]++;
}
for(int i=1;i<=sum;i++)
{
if(du[i]==0) tmp++,out=cnt[i];
}
printf("%d\n",(tmp==0||tmp>1) ? 0 : out);
return 0;
}