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);
}

本文介绍了一种通过Tarjan算法解决计算图中被所有其他点可达的超级节点数量的问题。利用Tarjan缩点法,文章详细展示了如何找出图中唯一的无出度超级节点,并以此确定最终答案。
4万+

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



