您的位置:首页 > 运维架构

POJ 2186 Popular Cows

2014-01-22 22:34 288 查看
抽象成:在一个有向图中,找所有的点都可以到达的点的个数

根据题意结果必在一个强连通分量里(所有的答案之间肯定互相能到达)。用tarjan找出所有的连通分量,如果某个连通分量里有连到外面的边,则这个分量肯定不会是答案(分量图是有向的无环图,从分量1里连线到分量2中的边,分量2肯定没有变连回分量1,也就是1到达了2但是2不能到达1)。如果没有向外连边的连通分量不是1个就没有答案。

Popular Cows

Time Limit: 2000MS Memory Limit: 65536K
Total Submissions: 21376 Accepted: 8732
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. 

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. 

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

Hint

Cow 3 is the only cow of high popularity. 

Source

USACO 2003 Fall
[Submit]   [Go Back]   [Status]  
[Discuss]

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>

using namespace std;

const int maxV=11000,maxE=55000;

struct Edge
{
int to,next;
}edge[maxE];

int Adj[maxV],Size;

void init()
{
Size=0;
memset(Adj,-1,sizeof(Adj));
}

void Add_Edge(int u,int v)
{
edge[Size].to=v;
edge[Size].next=Adj[u];
Adj[u]=Size++;
}

int Low[maxV],DFN[maxV],Stack[maxV],Belong[maxV],num[maxV];
int Index,top,scc,n;

bool Instack[maxV];

void tarjan(int u)
{
int v;
Low[u]=DFN[u]=++Index;
Stack[top++]=u;
Instack[u]=true;

for(int i=Adj[u];~i;i=edge[i].next)
{
v=edge[i].to;
if(!DFN[v])
{
tarjan(v);
Low[u]=min(Low[u],Low[v]);
}
else if(Instack[v])
{
Low[u]=min(Low[u],DFN[v]);
}
}

if(Low[u]==DFN[u])
{
scc++;
do
{
v=Stack[--top];
Instack[v]=false;
num[scc]++;
Belong[v]=scc;
}while(v!=u);
}
}

int solve(int n)
{
memset(DFN,0,sizeof(DFN));
memset(Instack,false,sizeof(Instack));
memset(num,0,sizeof(num));

Index=scc=top=0;

for(int i=1;i<=n;i++)
{
if(!DFN[i]) tarjan(i);
}

return scc;
}

bool yes[maxV];

int main()
{
int m;
while(scanf("%d%d",&n,&m)!=EOF&&n)
{
init();
memset(yes,true,sizeof(yes));
int a,b;
for(int i=0;i<m;i++)
{
scanf("%d%d",&a,&b);
Add_Edge(a,b);
}
int scc=solve(n);

for(int i=1;i<=n;i++)
{
for(int j=Adj[i];~j;j=edge[j].next)
{
int v=edge[j].to,u=i;
if(Belong[v]!=Belong[u])
{
yes[Belong[u]]=false;
}
}
}

int ans=0,tot=0;

for(int i=1;i<=scc;i++)
{
if(yes[i])
{
tot++;
ans+=num[i];
}
}

if(tot!=1) ans=0;
printf("%d\n",ans);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息