赞
踩
program tarjan;
type node=^rec;
rec=record
next:node;
name:longint;
end;
var stack:array[1..1000] of longint; {栈}
can:array[1..1000] of boolean;{栈内标记,true 表示在栈中}
dfn:array[1..1000] of longint;{DFN搜索序}
belong:array[1..1000] of longint;{连通分量标志数组}
low:array[1..1000] of longint;{low追溯最初位置}
vertex:array[1..1000] of node;{顶点表}
top,belongx,n:longint;{top栈顶指针,belongx连通分量标志}
step,x,y,m,i:longint;
procedure insert(x,y:longint); {建图,邻接表}
var p:node;
begin
new(p);
p^.next:=vertex[x];
p^.name:=y;
vertex[x]:=p;
end;
procedure tarjan(i:longint);
var j:longint;
p:node;
begin
step:=step+1;
dfn[i]:=step;
low[i]:=step;
can[i]:=true;
top:=top+1;
stack[top]:=i;
p:=vertex[i];
while p<>nil do
begin
j:=p^.name;
p:=p^.next; {取出下一条边}
if dfn[j]=0
then
begin
tarjan(j);
if low[j]<low[i] {i能够找到j,所以j能够回溯到的i肯定能够找到,比较哪个回溯更远}
then
low[i]:=low[j];
end
else
begin
if can[j] and (low[j]<low[i]) {如果j已经在栈中,并且j的回溯比i远,那么就将i的回溯换为j的回溯,如果j不在栈中又DFN[j]<>0那么j必然在以前搜过且退栈,即已在另一个环中且i不在这个环上}
then
low[i]:=low[j];
end;
end;
if dfn[i]=low[i] {如果dfn[i]=low[i]就说明找到一个连通分量,因为既搜索到i,又回溯到i,构成了一个回路}
then
begin
inc(belongx);
repeat {弹栈}
j:=stack[top];
stack[top]:=0;
top:=top-1;
can[j]:=false;
belong[j]:=belongx;
until (j=i)
end;
end;
begin
assign(input,'D:/input/tarjan.txt');
reset(input);
assign(output,'D:/output/tarjan.txt');
rewrite(output);
readln(n,m);
for i:=1 to n do
begin
dfn[i]:=0;
low[i]:=0;
vertex[i]:=nil;
can[i]:=false;
end;
for i:=1 to m do
begin
readln(x,y);
insert(x,y);
end;
top:=0;
step:=0;
for i:=1 to n do
begin
if dfn[i]=0
then tarjan(i);
end;
for i:=1 to n do
write(i, ' ');
writeln;
for i:=1 to n do
write(belong[i],' ');
close(input);
close(output);
end.
大致就是这样了。。。
呃呃,自力更生。
去各大网站找就好了。。。
青春是用意志的血滴和拼搏的汗水酿成的琼浆——历久弥香;青春是用不凋的希望和不灭的向往编织的彩虹——绚丽辉煌;青春是用永恒的执著和顽强的韧劲筑起的一道铜墙铁壁——固若金汤。
点点滴滴汇成往事,往事又如泉水般涌入脑海。。。
赶脚每日一句都快成我的日记了。。呃呃,无视这句话吧。。。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。