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.

 

posted on 2013-11-20 14:32  BLADEVIL  阅读(...)  评论(... 编辑 收藏

统计