Description
Every 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.
【题目分析】
大概就是一个有向图,判断有多少个点,所有的点都能到达。直接搜索会TLE。那么我们考虑一下,在一个强联通分量中的任意两点之间肯定能够到达。那么先缩点,然后判断哪些点出度为零,那么这个点的大小就是答案。
考虑一下其他的点,有出边肯定不是答案,应为如果是,它会和自己的儿子合成一个强联通分量。而且当出度为零的点多于1时,此图无解,因为这几个出度为零的点谁也不会到达谁。
【代码】
第一次for循环写错了,WA了三次
#include <cstdio>
#include <cstring>
#include <cmath>
#include <stack>
#define M(a) memset(a,-1,sizeof a)
using namespace std;
stack<int>sta;
int h[100001],ne[100001],fr[100001],to[100001],en=0;
int in[100001],dfn[100001],low[100001],dcnt=0,index=0,belong[100001];
int big[100001],chu[100001],ru[100001];
inline void add(int a,int b)
{fr[en]=a;to[en]=b;ne[en]=h[a];h[a]=en++;}
inline int min(int a,int b)
{return a>b?b:a;}
inline void dfs(int u)
{
in[u]=1;
dfn[u]=low[u]=++index;
sta.push(u);
for (int i=h[u];i!=-1;i=ne[i])
{
if (!dfn[to[i]]) dfs(to[i]),low[u]=min(low[u],low[to[i]]);
else if (in[to[i]]) low[u]=min(low[u],dfn[to[i]]);
}
if (low[u]==dfn[u])
{
dcnt++;
int now=0;
while (1)
{
int x=sta.top();
sta.pop();
belong[x]=dcnt;
in[x]=0;
now++;
if (x==u) break;
}
big[dcnt]=now;
}
}
int main()
{
M(h);M(ne);M(fr);M(to);
int n,m;
scanf("%d%d",&n,&m);
for (int i=1;i<=m;++i)
{
int a,b;
scanf("%d%d",&a,&b);
add(a,b);
}
for (int i=1;i<=n;++i) if (!dfn[i]) dfs(i);
for (int i=0;i<m;++i)
{
if (belong[fr[i]]!=belong[to[i]])
chu[belong[fr[i]]]++,ru[belong[to[i]]]++;
}
int all=0,p=-1;;
for (int i=1;i<=dcnt;++i)
{if (!chu[i]) p=i,all++;}
if (all>=2) printf("0\n");
else printf("%d\n",big[p]);
}
4万+

被折叠的 条评论
为什么被折叠?



