求大佬帮忙看一下代码
查看原帖
求大佬帮忙看一下代码
675572
syyyyhy楼主2022/3/17 13:31

思路就是把找出强连通分量,然后把强连通分量看成一个超级点,判断超级点的出度,如果只有这一个分量出度为0,那么这连通分量里面的所有牛都是明星牛,否则没有明星牛

//奶牛缩点
#include <bits/stdc++.h>
using namespace std;

int n,m;
int x[50020];
int y[50020];
int dfn[10020];
int low[10020];
int vis[10020];
int instake[10020];
vector<int> stake;
vector<int> g[10020];
int col[10020];
int sum[10020];
int time2=1;
int tt=0;
int chu[10020];
void tarjan(int num)
{
	stake.push_back(num);
	vis[num]=1;
	dfn[num]=time2;
	low[num]=time2;
	time2++;
	for(int j=0;j<g[num].size();j++)
	{
		int v=g[num][j];
		if(!dfn[v])
		{
			tarjan(v);
			low[num]=min(low[num],low[v]);
		}
		else if(vis[v])
		{
			low[num]=min(low[num],low[v]);
		}
	}
	
	if(low[num]==dfn[num])
	{
		tt++;
		while(stake[stake.size()-1]!=num)
		{
			int m1=stake[stake.size()-1];
			stake.pop_back();
			vis[m1]=0;
			col[m1]=tt;
			sum[tt]++; 
		}
		int m1=stake[stake.size()-1];
		stake.pop_back();
		vis[m1]=0;
		col[m1]=tt;
		sum[tt]++; 
	}
}
int main()
{
	cin>>n>>m;
	for(int i=2;i<=m;i++)
	{
		cin>>x[i]>>y[i];
		g[x[i]].push_back(y[i]);
	}
	
	for(int i=1;i<=n;i++)
	{
		if(!dfn[i])
		{
			tarjan(i);
		}
	}
	
	memset(g,0,sizeof(g));
	for(int i=1;i<=m;i++)
	{
		if(col[x[i]]!=col[y[i]])
		{
			chu[col[x[i]]]++;
		}
	}
	
	int k=0;
	int count=0;
	for(int i=1;i<=tt;i++)
	{
		if(!chu[i])
		{
			k=i;	
		}
		else count++;
	}
	if(count>=2) cout<<0;
	else cout<<sum[k];
 } 
2022/3/17 13:31
加载中...