(缩点)受欢迎的牛

题目传送门sxazr
题目中奶牛之间的喜欢具有传递性,可以在有向图中找出强联通子图,每个子图中的奶牛都是相互喜欢的。
把每个强联通子图找出来,缩点,再看看有没有出度为0的点;如果出度为0的点大于等于2,那么就没有明星奶牛了。在这里插入图片描述
如图,2和3两个点出度都为零,但2和3之间不喜欢;
上代码

#include <iostream>
#include <cstdio>
using namespace std;
int n,m,g,k[10001],st[10001],s[10001],top,hed[10001],net[50001],to[50001],dfn[10001],low[10001],num,co[10001],cnt;
void tarjan(int u)
{
	low[u]=dfn[u]=++num;
	st[++top]=u;
	for(int i=hed[u];i;i=net[i]){
		int v=to[i];
		if(!dfn[v]){
			sx(v);
			low[u]=min(low[v],low[u]);
		}
		else if(!co[v]) low[u]=min(low[v],low[u]);
	}
	if(low[u]==dfn[u]){
		co[u]=++cnt;s[cnt]++;
		while(st[top]!=u) co[st[top--]]=cnt,s[cnt]++;
		top--;
	}
}
int main()
{
	cin>>n>>m;
	for(int a,b,i=1;i<=m;i++){
		scanf("%d%d",&a,&b);
		net[++g]=hed[a];hed[a]=g;to[g]=b;
	}
	for(int i=1;i<=n;i++)
	 if(!dfn[i]) tarjan(i);
	for(int i=1;i<=n;i++)
	  for(int j=hed[i];j;j=net[j])
	    if(co[i]!=co[to[j]]) k[co[i]]++;
	top=0;
	for(int i=1;i<=cnt;i++)
	  if(k[i]==0) top++,g=s[i];
	cout<<(top==1?g:0);
	return 0; 
}```

猜你喜欢

转载自blog.csdn.net/qq_42920137/article/details/88084561
今日推荐