LOJ #10091. 「一本通 3.5 例 1」受欢迎的牛
https://loj.ac/problem/10091
题目描述
原题来自:USACO 2003 Fall
每一头牛的愿望就是变成一头最受欢迎的牛。现在有 NNN 头牛,给你 MMM 对整数 (A,B)(A,B)(A,B),表示牛 AAA 认为牛 BBB 受欢迎。这种关系是具有传递性的,如果 AAA 认为 BBB 受欢迎,BBB 认为 CCC 受欢迎,那么牛 AAA 也认为牛 CCC 受欢迎。你的任务是求出有多少头牛被除自己之外的所有牛认为是受欢迎的。
输入格式
第一行两个数 N,MN,MN,M;
接下来 MMM 行,每行两个数 A,BA,BA,B,意思是 AAA 认为 BBB 是受欢迎的(给出的信息有可能重复,即有可能出现多个 A,BA,BA,B)。
输出格式
输出被除自己之外的所有牛认为是受欢迎的牛的数量。
样例
样例输入
3 3
1 2
2 1
2 3
样例输出
1
样例说明
只有第三头牛被除自己之外的所有牛认为是受欢迎的。
数据范围与提示
对于全部数据,1≤N≤104,1≤M≤5×1041le Nle 10^4,1le Mle 5 imes 10^41≤N≤104,1≤M≤5×104。
当这是一棵树的时候,很容易看出求每个点的出度,输出是否存在出度为0的点
(如果有多个结点,是不可能有奶牛被其余牛都欢迎,答案为0)
但这是一个有向图,所以要缩点后进行如上的操作
#include<cstdio>
#include<iostream>
using namespace std;
int read()
{
int ret=0;
char ch=getchar();
while(ch<"0"||ch>"9") ch=getchar();
while(ch>="0"&&ch<="9")
ret=(ret<<1)+(ret<<3)+ch-"0",ch=getchar();
return ret;
}
const int N=1e6+4;
int n,m,a[N],d[N],ans;
int he[N],to[N],nxt[N],cnt;
int dfn[N],sgn,low[N],st[N],top,co[N],col;
struct NA{
int u,v;
}e[N];
inline void add(int u,int v)
{
to[++cnt]=v;
nxt[cnt]=he[u];
he[u]=cnt;
}
void Tarjan(int u)
{
dfn[u]=low[u]=++sgn;
st[++top]=u;
for(int e=he[u];e;e=nxt[e])
{
int v=to[e];
if(!dfn[v])
Tarjan(v),low[u]=min(low[u],low[v]);
else if(!co[v])
low[u]=min(low[u],dfn[v]);
}
if(dfn[u]==low[u])
{
co[u]=++col;
while(top&&st[top]!=u)
co[st[top--]]=col;
top--;
}
}
int main()
{
n=read(),m=read();
for(int i=1;i<=m;i++)
e[i].u=read(),e[i].v=read(),
add(e[i].u,e[i].v);
for(int i=1;i<=n;i++)
if(!dfn[i]) Tarjan(i);
for(int i=1;i<=n;i++)
a[co[i]]++;
for(int i=1;i<=m;i++)
if(co[e[i].v]!=co[e[i].u])
d[co[e[i].u]]++;
for(int i=1;i<=col;i++)
if(!d[i])
{
if(!ans) ans=a[i];
else
{
ans=0; break;
}
}
printf("%d
",ans);
}
声明:该文观点仅代表作者本人,牛骨文系教育信息发布平台,牛骨文仅提供信息存储空间服务。