P2341 [USACO03FALL / HAOI2006] 受欢迎的牛 G


Day3 Tarjan


代码如下(示例):

#include <bits/stdc++.h>
using namespace std;
const int MaxN=1e4+5;//最大点数
const int MaxM=5e4+5;//最大边数 
int to[MaxM],nex[MaxM],fir[MaxN];
int col,num,dfn[MaxN],low[MaxN],de[MaxN],si[MaxN];
int tot=0,co[MaxN],n,m;
int top,st[MaxN];


inline void Ins(int x,int y){//链式前向星 
	to[++tot]=y;
	nex[tot]=fir[x];
	fir[x]=tot;
} 

void Tarjan(int u){//缩点
   dfn[u]=low[u]=++num;
   st[++top]=u;//模拟栈
   for(int i=fir[u];i;i=nex[i]){
   	 int v=to[i];
   	 if(!dfn[v]){
   	   Tarjan(v);//先将子树的状态完成 
	   low[u]=min(low[u],low[v]);		
	 }
	 else if(!co[v])//还在栈中
	   low[u]=min(low[u],low[v]);	
   }
   if(low[u]==dfn[u]){
   	 co[u]=++col;
   	 ++si[col];
   	 while(st[top]!=u){
   	   ++si[col];
   	   co[st[top]]=col;
   	   --top;
	 }
	 --top;
   } 	
}

int main(){
	cin>>n>>m;
	for(int i=1,x,y;i<=m;i++){
		cin>>x>>y;
		Ins(y,x);//反向建边 
	}
	for(int i=1;i<=n;i++){
		if(!dfn[i])
		  Tarjan(i);//缩点 
	}
	for(int i=1;i<=n;i++)
	  for(int j=fir[i];j;j=nex[j])
	    if(co[i]!=co[to[j]])
	      de[co[to[j]]]++;//入度增加
    int ans =0,u=0;
	for(int i=1;i<=col;i++)
	  if(!de[i])
	    ans=si[i],u++;//统计
	if(u==1)
	  cout<<ans<<endl;
	else
	  cout<<0<<endl;
	return 0;
	  
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值