http://www.cnblogs.com/live-no-regrets/

POJ 1236 Tarjan缩点+统计出入度

毫无理由地献上证明:(其实就是Tarjan缩点以后做)
https://blog.csdn.net/tomandjake_/article/details/81842963

 

#include<iostream>
#include<string.h>
#define N 150
using namespace std;
int dfn[N],low[N],id[N],a[N][N],n,past[N],pl,cnt,sum;
bool vis[N],pre[N],suf[N];
void tarjan(int x)
{
	dfn[x]=low[x]=++sum;
	past[++pl]=x;
	for (int i=1;i<=n;i++)
		if (!vis[i]&&a[x][i]>0){
			if (low[i]==0x3f3f3f3f)tarjan(i);
			low[x]=(low[x]<low[i])?low[x]:low[i];
		}
	if (low[x]==dfn[x]){
		++cnt;
		do{
			int now=past[pl];
			id[now]=cnt;
		} while (past[pl--]!=x);
	}
	vis[x]=true;
}
void trans()
{
	memset(pre,false,sizeof(pre));memset(suf,false,sizeof(suf));
	for (int i=1;i<=n;i++)
		for (int j=1;j<=n;j++)
			if (id[i]!=id[j]&&a[i][j])pre[id[j]]=true,suf[id[i]]=true;
}
int main()
{
	cin>>n;
	memset(a,0,sizeof(a));
	for (int i=1;i<=n;i++){
		int v;
		while (true){
			cin>>v;
			if (v==0)break;
			a[i][v]=1;
		}
	}
	memset(dfn,0,sizeof(dfn));memset(low,0x3f,sizeof(low));memset(vis,false,sizeof(vis));
	cnt=0,sum=0;pl=0;
	for (int i=1;i<=n;i++)
		if (!vis[i])tarjan(i);
	
	if (cnt==1){cout<<"1\n0\n";return 0;}
	
	trans();
	int sum1=0,sum2=0;
	for (int i=1;i<=cnt;i++){
		if (!pre[i])sum1++;
		if (!suf[i])sum2++;
	}
	cout<<sum1<<"\n"<<((sum1>sum2)?sum1:sum2)<<"\n";
	return 0;
}

  

posted @ 2020-11-28 20:31  voyage~st~Imagine  阅读(74)  评论(0编辑  收藏  举报