tarjan模板
  • 板块学术版
  • 楼主夜阑
  • 当前回复0
  • 已保存回复0
  • 发布时间2022/8/8 15:07
  • 上次更新2023/10/27 16:27:33
查看原帖
tarjan模板
243263
夜阑楼主2022/8/8 15:07

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

WA48分

#include<bits/stdc++.h>
using namespace std;
struct node{int x,to,next;}bian[100010];
int n,m,bcnt,head[100010];
int num,cnt;
int spz[100010],sp=1;
int vis[100010];
int ins[100010];
int dfn[100010];
int low[100010];
//////////缩点后的变量
int clr[100010];//color染色,同一个缩点是同一个颜色,颜色用cnt表示 
int out[100010];//记录每个颜色的出边个数 
int all[100010];//记录每个颜色的点的个数 
void push(int x){spz[sp++]=x;}
int pop(){
	if(sp==1)return -1;
	return spz[--sp]; 
} 
void tj(int x){
	dfn[x]=low[x]=++num;
	push(x);ins[x]=1;vis[x]=1;
	for(int k=head[x];k;k=bian[k].next){
		if(vis[bian[k].to]==0){
			tj(bian[k].to);
			low[x]=min(low[x],low[bian[k].to]);
		}
		else if(ins[bian[k].to]==1)low[x]=min(low[x],dfn[bian[k].to]);
	}
	if(low[x]==dfn[x]){
		cnt++;//分量个数++;
		int t;//这个颜色有几个点 
		do{
			t=pop();//出栈 
			ins[t]=0;clr[t]=cnt; 
			all[cnt]++;
			if(t==-1)break;
		}
		while(t!=x); 
	}
}
void add(int x,int y){
	bcnt++;
	bian[bcnt].x=x;
	bian[bcnt].to=y;
	bian[bcnt].next=head[x];
	head[x]=cnt;
}
int main(){
	cin>>n>>m;
	for(int i=1;i<=m;i++){
		int u,v;cin>>u>>v;
		add(u,v);
	}
	for(int i=1;i<=n;i++)
		if(vis[i]==0)tj(i);
	for(int k=1;k<=m;k++){//遍历找出边 
		if(clr[bian[k].x]!=clr[bian[k].to])//跨分量的边 
			out[bian[k].x]++; 
	}
	int sum=0,rpt;//sum:出度为0个数,rpt:哪个颜色出度为0 
	for(int i=1;i<=cnt;i++){//看有几个出度为0 
		if(out[i]==0){
			sum++;rpt=i;
		}
	}
	if(sum!=1)cout<<0;
	else cout<<all[rpt];
	return 0;
} 
2022/8/8 15:07
加载中...