Popular Cows
Time Limit: 2000MS | Memory Limit: 65536K | |
Total Submissions: 24359 | Accepted: 9999 |
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.
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.
Input
* Line 1: Two space-separated integers, N and M
* Lines 2..1+M: Two space-separated numbers A and B, meaning that A thinks B is popular.
* Lines 2..1+M: Two space-separated numbers A and B, meaning that A thinks B is popular.
Output
* Line 1: A single integer that is the number of cows who are considered popular by every other cow.
Sample Input
3 3 1 2 2 1 2 3
Sample Output
1
题意:给定一些点和单向边,问有多少点使得其他所有的点到这个点都存在路径。
思路:Tarjan缩点后,如果有且仅有一个点的出度为0,那么这个点内的点的数目就是最后的答案。
AC代码如下:
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
struct node
{
int v,next;
}edge[50010];
int n,m,Head[10010],DFN[10010],Low[10010],stack[10010],scnt,cnt,tot,top,Belong[10010];
bool instack[10010],flag;
int num[10010],in[10010],out[10010];
void add(int u,int v)
{
edge[tot].v=v;
edge[tot].next=Head[u];
Head[u]=tot++;
}
void Tarjan(int u)
{
int i,j,k,v;
DFN[u]=Low[u]=++cnt;
stack[top++]=u;
instack[u]=1;
for(i=Head[u];i!=-1;i=edge[i].next)
{
v=edge[i].v;
if(!DFN[v])
{
Tarjan(v);
Low[u]=min(Low[u],Low[v]);
}
else if(instack[v])
Low[u]=min(Low[u],DFN[v]);
}
if(DFN[u]==Low[u])
{
scnt++;
do
{
v=stack[--top];
instack[v]=0;
Belong[v]=scnt;
num[scnt]++;
}while(u!=v);
}
}
int main()
{
int i,j,k,u,v,ans;
memset(Head,-1,sizeof(Head));
scanf("%d%d",&n,&m);
for(i=1;i<=m;i++)
{
scanf("%d%d",&u,&v);
add(u,v);
}
for(i=1;i<=n;i++)
if(!DFN[i])
Tarjan(i);
for(u=1;u<=n;u++)
for(j=Head[u];j!=-1;j=edge[j].next)
{
v=edge[j].v;
if(Belong[u]!=Belong[v])
{
out[Belong[u]]++;
in[Belong[v]]++;
}
}
k=0;
for(i=1;i<=scnt;i++)
if(out[i]==0)
{
k++;
ans=num[i];
}
if(k!=1)
ans=0;
printf("%d\n",ans);
}