【图论】【强连通分量】【Tarjan】pascal+邻接表

const
    maxn = 100000;
    maxm = 2*maxn;
var
    cost,toit,next:array[0..maxm] of longint;
    list,dfn,low,stack:array[0..maxn] of longint;   
    n,m,top,i,j,d,tot,a,b,c:longint;
    f,vis:array[0..maxn] of boolean;

procedure add(a,b,c:longint);
begin
    inc(tot);
    cost[tot]:=c;
    toit[tot]:=b;
    next[tot]:=list[a];
    list[a]:=tot;
end;

function min(a,b:longint):longint;
begin
    if athen exit(a)
    else exit(b);
end;

procedure print(x:integer);
begin
    while stack[tot]<>x do begin
        writeln(stack[tot],' ');
        f[stack[tot]]:=false;
        dec(tot);
    end;
    writeln(stack[tot]);
    f[stack[tot]]:=false;
    dec(tot);
end;

procedure dfs(x:integer);
var i,k,v:longint;
begin
    inc(d);
    dfn[x]:=d;
    low[x]:=d;
    inc(tot);
    stack[tot]:=x;
    f[x]:=true;
    k:=list[x];
    while k<>0 do begin
        v:=toit[k];
        if not vis[v] then begin
            vis[v]:=true;
            dfs(v);
            low[x]:=min(low[x],low[v]);
        end
        else if f[v] then low[x]:=min(low[x],dfn[v]);
        k:=next[k];
    end;
    if dfn[x]=low[x] then print(x);
end;

begin
    fillchar(list,sizeof(list),0);
    fillchar(next,sizeof(next),0);
    fillchar(toit,sizeof(toit),0);
    fillchar(f,sizeof(f),false);
    fillchar(vis,sizeof(vis),false);
    readln(n,m);
    tot:=0;
    for i:=1 to m do begin
        readln(a,b);
        add(a,b);
    end;    
    d:=0;tot:=0;
    for i:=1 to n do if not vis[i] then begin
        vis[i]:=true;
        dfs(i);
    end; 
end.

你可能感兴趣的:(图论)