luogu_2341 tarjan图论

传送门

https://www.luogu.org/problemnew/show/P2341

思路

  1. 先缩点(tarjan版子)
  2. 只能有一个强联通分量的出度为0
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
int read()
{
	char ch=' ';
	int f=1;int x=0;
	while(ch<'0'||ch>'9')
	{
		if(ch=='-') f=-1;ch=getchar();
	}
	while(ch>='0'&&ch<='9')
	{
	    x=x*10+ch-'0';ch=getchar();
	}
	return x*f;
}
const int N=10100;
const int M=51000;
int dfn[N];
int low[N];
struct node
{
	int v,nxt;
}edge[M];
int head[N],cnt;
void add(int u,int v)
{
	cnt++;
	edge[cnt].v=v;
	edge[cnt].nxt=head[u];
	head[u]=cnt;
}
int t;
bool instack[N];
int stack[N],top;
int cc,belong[N];
int siz[N];
void dfs(int now)
{
	t++;
	dfn[now]=low[now]=t;
	stack[++top]=now;
	instack[now]=true;
	for(int i=head[now];i;i=edge[i].nxt)
	{
		int v=edge[i].v;
		if(!dfn[v])
		{
			dfs(v);
			low[now]=min(low[now],low[v]);
		}
		else
		{
			if(instack[v])
			{
				low[now]=min(low[now],dfn[v]);
			}
		}
	}
	if(low[now]==dfn[now])
	{
		cc++;
		while(stack[top]!=now)
		{
			siz[cc]++;
			belong[stack[top]]=cc;
			instack[stack[top]]=false;
			top--;
		}
		siz[cc]++;
		belong[now]=cc;
		instack[now]=false;
		top--;
	}
}
int out[N];
int main()
{
	int n,m;
	n=read();m=read();
	int i,j;
	for(i=1;i<=m;i++)
	{
		int u,v;
		u=read();v=read();
		add(u,v);
	} 
	for(i=1;i<=n;i++)
	{
		if(!dfn[i])
		{
			dfs(i);
		}
	}
	for(i=1;i<=n;i++)
	{
		for(j=head[i];j;j=edge[j].nxt)
		{
			int v=edge[j].v;
			if(belong[v]!=belong[i])
			{
				out[belong[i]]++;
			}
		}
	}
	int sum=0;
	int pos;
	for(i=1;i<=cc;i++)
	{
		if(out[i]==0)
		{
			sum++;
			pos=i;
		}
	}
	if(sum==1)
	{
		cout<<siz[pos]<<endl;
	}
	else 
	{
		cout<<"0"<<endl;
	}
	return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_42110318/article/details/83576794
今日推荐