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

POJ2186-Popular Cows

2017-08-22 21:58 267 查看

Popular Cows

Time Limit: 2000MS Memory Limit: 65536K

Total Submissions: 35075 Accepted: 14295

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

题目大意:有n头牛,有单向喜欢关系,具有传递性,问受所有牛喜欢的牛有多少个。

解题思路: Tarjan求强连通分量,缩点,判断出度为0的点是否只有一个,若是,则输出该强连通分量里点的个数。

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<string>
using namespace std;
const int MAXN=2e5+5;
const int MAXM=5e5+5;
int head[MAXN],tot;
int low[MAXN],dfn[MAXN],sta[MAXN],bel[MAXN];//bel数组的值是1~scc
int index,top;
int scc;//强连通分量的个数
bool instack[MAXN];
int num[MAXN];//各个强连通分量包含点的个数,数组编号1~scc
//num数组不一定需要,结合实际情况
int n,m;

struct Edge
{
int from,to,nxt;
}edge[MAXM];

void addedge(int u,int v)
{
edge[tot].from=u;
edge[tot].to=v;
edge[tot].nxt=head[u];
head[u]=tot++;
}

void tarjan(int u)
{
int v;
low[u]=dfn[u]=++index;
sta[top++]=u;
instack[u]=true;
for(int i=head[u];i!=-1;i=edge[i].nxt)
{
v=edge[i].to;
if(!dfn[v])
{
tarjan(v);
if(low[u]>low[v]) low[u]=low[v];
}else if(instack[v]&&low[u]>dfn[v])
low[u]=dfn[v];
}
if(low[u]==dfn[u])
{
scc++;
do
{
v=sta[--top];
instack[v]=false;
bel[v]=scc;
num[scc]++;
}while(v!=u);
}
}

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

void init()
{
tot=0;
memset(head,-1,sizeof(head));
}

int out[MAXN];

void suodian()
{
memset(out,0,sizeof(out));
//for(int i=1;i<=scc;i++) G[i].clear();
for(int i=0;i<m;i++)
{
int u=bel[edge[i].from];
int v=bel[edge[i].to];
if(u!=v)
out[u]++;
}
int cnt=0,p;
for(int i=1;i<=scc;i++)
{
if(out[i]==0)
{
cnt++;
p=i;
}
}
if(cnt!=1) printf("0\n");
else
{
printf("%d\n",num[p]);
}
}
int main()
{

while(scanf("%d%d",&n,&m)!=EOF)
{
init();
int u,v;
for(int i=1;i<=m;i++)
{
scanf("%d%d",&u,&v);
addedge(u,v);
}
solve(n);
//        cout<<scc<<endl;
//        for(int i=1;i<=n;i++)
//        {
//            cout<<bel[i]<<endl;
//        }
//        cout<<num[1]<<" "<<num[2]<<endl;
suodian();
}
return 0;
}
/*
3 3
1 2
2 1
2 3
*/
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: