bzoj 1051 tarjan强连通分量

2013-11-16 11:39

原题传送门http://www.lydsy.com/JudgeOnline/problem.php?id=1051

强连通分量,缩完点之后看出度为0的强连通分量有几个,如果只有一个则输出该强连通分量的点数,否则输出0;

/**************************************************************

    Problem: 1051

    User: BLADEVIL

    Language: Pascal

    Result: Accepted

    Time:124 ms

    Memory:1396 kb

****************************************************************/

 

//By BLADEVIL

var

    n, m                        :longint;

    pre, other                  :array[0..100010] of longint;

    last                        :array[0..20010] of longint;

    l                           :longint;

    flag                        :array[0..10010] of boolean;

    dfn, low                    :array[0..10010] of longint;

    time                        :longint;

    tot                         :longint;

    stack                       :array[0..10010] of longint;

    key                         :array[0..10010] of longint;

    size                        :array[0..10010] of longint;

    full                        :longint;

    father                      :array[0..20010] of longint;

     

function min(a,b:longint):longint;

begin

    if a>b then min:=b else min:=a;

end;   

 

procedure connect(x,y:longint);

begin

    inc(l);

    pre[l]:=last[x];

    last[x]:=l;

    other[l]:=y;

end;

     

procedure init;

var

    i                           :longint;

    x, y                        :longint;

begin

    read(n,m);

    for i:=1 to m do

    begin

        read(x,y);

        connect(y,x);

    end;

end;

 

procedure dfs(x:longint);

var

    q, p                        :longint;

    cur                         :longint;

begin

    inc(time);

    dfn[x]:=time;

    low[x]:=time;

    flag[x]:=true;

    inc(tot);

    stack[tot]:=x;

     

    q:=last[x];

    while q<>0 do

    begin

        p:=other[q];

        if dfn[p]=0 then

        begin

            dfs(p);

            low[x]:=min(low[x],low[p]);

        end else

        if flag[p] then low[x]:=min(low[x],dfn[p]);

        q:=pre[q];

    end;

     

    cur:=-1;

    if dfn[x]=low[x] then

    begin

        while cur<>x do

        begin

            cur:=stack[tot];

            dec(tot);

            flag[cur]:=false;

            key[cur]:=x+n;

            inc(size[key[cur]]);

        end;

    end;

end;

 

procedure main;

var

    i                           :longint;

    q, p                        :longint;

begin

    for i:=1 to n do if dfn[i]=0 then dfs(i);

    for i:=1 to n do

    begin

        q:=last[i];

        while q<>0 do

        begin

            p:=other[q];

            if key[i]<>key[p] then

            begin

                connect(key[i],key[p]);

                father[key[p]]:=key[i];

            end;

            q:=pre[q];

        end;

    end;

    full:=-1;

    for i:=1 to n do

    begin

        if (father[key[i]]=0) and (full=-1) then full:=key[i];

        if (father[key[i]]=0) and (full<>-1) and (full<>key[i]) then

        begin

            writeln(0);

            exit;

        end;

    end;

    writeln(size[full]);

end;

 

begin

    init;

    main;

end.

 

你可能感兴趣的:(tar)