受欢迎的牛(强连通分量)
Posted SSL_LKJ
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了受欢迎的牛(强连通分量)相关的知识,希望对你有一定的参考价值。
受欢迎的牛
解题思路
先缩点成一个有向无环图
如果只有一个出度为0的点
那么这个新图中出度为0的点所代表的牛都是明星
输出该强连通分量中的点数
否则没有牛成为明星
输出0
AC代码
#include<iostream>
#include<cstdio>
using namespace std;
int n,m,ok,top,tot,ans,T,TT,du[50005],low[50005],col[50005],dfn[50005],sum[50005],stak[50005],head[50005];
struct node
{
int to,next;
}a[50005];
void add(int x,int y)//建边
{
a[++tot]=(node){y,head[x]};
head[x]=tot;
}
void Tarjan(int x)//求强连通分量缩点
{
dfn[x]=low[x]=++T;
stak[++top]=x;
for(int i=head[x];i;i=a[i].next)
{
int v=a[i].to;
if(!dfn[v])
{
Tarjan(v);
low[x]=min(low[x],low[v]);
}
else if(!col[v])low[x]=min(low[x],low[v]);
}
if(dfn[x]==low[x])
{
col[x]=++TT;
sum[TT]=1;
while(stak[top]!=x)
sum[TT]++,col[stak[top--]]=TT;
top--;
}
return;
}
int main()
{
scanf("%d%d",&n,&m);
for(int i=1;i<=m;i++)
{
int x,y;
scanf("%d%d",&x,&y);
add(x,y);
}
for(int i=1;i<=n;i++)
if(!dfn[i])Tarjan(i);
for(int i=1;i<=n;i++)
for(int j=head[i];j;j=a[j].next)//枚举
{
int v=a[j].to;
if(col[i]!=col[v])du[col[i]]++;
}
for(int i=1;i<=TT;i++)
if(!du[i])ans=sum[i],ok++;
if(ok!=1)printf("0");
else printf("%d",ans);
return 0;
}
谢谢
以上是关于受欢迎的牛(强连通分量)的主要内容,如果未能解决你的问题,请参考以下文章
P2341 [HAOI2006]受欢迎的牛|模板强连通分量(tarjan)