算法模板:tarjan模板

tarjan模板pascal 

//tarjan模板
var
	i,n,m,x,y,total,so:longint;
	h,dfn,low,ss,g1:array[1..10000]of longint;
	bz:array[1..10000]of boolean;
	z:array[0..10000]of longint;
	g,l:array[1..30000]of longint;
procedure ad(x,y:longint);		//前向星存边
begin
	inc(so);g[so]:=y;l[so]:=h[x];h[x]:=so;
end;
function min(x,y:longint):longint;
begin
	if x<y then exit(x)
	else exit(y);
end;
procedure dg(x:longint);
var
	i:longint;
begin
	i:=h[x];
	while i<>0 do
	begin
		if dfn[g[i]]=0 then  //没有到过这个点
		begin
			inc(z[0]);		//加入栈
			z[z[0]]:=g[i];	
			bz[g[i]]:=true;	//打上入栈标记
			inc(total);dfn[g[i]]:=total;low[g[i]]:=total;  //初始化
			dg(g[i]);	
			low[x]:=min(low[x],low[g[i]]);  //更新low(点在这颗树中的,最小的子树的根)
		end
		else if bz[g[i]]=true then low[x]:=min(low[x],low[g[i]]);  //如果此点未出栈,则更新low
		i:=l[i];
	end;
	if low[x]=dfn[x] then	
	begin
		while z[z[0]]<>x do  //未退到x
		begin
			bz[z[z[0]]]:=false;		//去除标记
			g1[z[z[0]-1]]:=z[z[0]];  //将前一个点连向当前点,这样在读取整个强联通分量时,
									//可以从头开始往下跳,一直跳到结尾,这样可以省空间,存下整个图的强联通分量
									//好像前向星的存边一样
			z[z[0]]:=0;				//抹除痕迹(可以删去)
			dec(z[0]);				//更新总数
			inc(ss[x]);				//更新强联通分量节点数
		end;
		bz[z[z[0]]]:=false;z[z[0]]:=0;inc(ss[x]);dec(z[0]);
	end;
end;
begin
	assign(input,'sf_tarjan.in');reset(input);
	assign(output,'sf_tarjan.out');rewrite(output);
	readln(n,m);
	for i:=1 to m do
	begin
		readln(x,y);
		ad(x,y);
	end;
	for i:=1 to n do
	begin
		if dfn[i]=0 then	//没有到过这个点
		begin
			inc(z[0]);z[z[0]]:=i;	//加入栈
			bz[i]:=true;	//打上入栈标记
			inc(total);		//更新总结点数
			dfn[i]:=total;low[i]:=total;	//初始化
			dg(i);
		end;
	end;
	close(input);
	close(output);
end.

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值