Online JudgeProblem SetAuthorsOnline ContestsUser
Web Board
Home Page
F.A.Qs
Statistical Charts
Problems
Submit Problem
Online Status
Prob.ID:
Register
Update your info
Authors ranklist
Current Contest
Past Contests
Scheduled Contests
Award Contest
User ID:
Password:
  Register

人生第一道强连通分量,调了两个小时,终于AC了。。。(以下附代码PASCAL版)

Posted by noipchampion at 2011-08-05 19:02:03 on Problem 2186
type
  node=record
         p,link:longint;
  end;

var head,f,s,c,dfn,low,oud:array[1..10000] of longint;
    edge:array[1..50000] of node;
    vis,inner:array[1..10000] of boolean;
    n,m,top,time,count:longint;

procedure init;
  var i,a,b:longint;

  begin
    readln(n,m);
    for i:=1 to m do
      begin
        readln(a,b);
        edge[i].p:=b;
        edge[i].link:=head[a];
        head[a]:=i;
      end;
  end;

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

  begin
    if a<b then exit(a) else exit(b);
  end;

procedure tarjan(x:longint);
  var k:longint;

  begin
    inc(top);
    s[top]:=x;
    inner[x]:=true;
    inc(time);
    dfn[x]:=time;
    low[x]:=time;
    k:=head[x];
    while k<>0 do
      begin
        if not vis[edge[k].p] then
          begin
            vis[edge[k].p]:=true;
            tarjan(edge[k].p);
            low[x]:=min(low[x],low[edge[k].p]);
          end
        else
          if inner[edge[k].p] then low[x]:=min(low[x],dfn[edge[k].p]);
        k:=edge[k].link;
      end;
    if dfn[x]=low[x] then
      begin
        inc(count);
        c[count]:=0;
        repeat
          inner[s[top]]:=false;
          f[s[top]]:=count;
          inc(c[count]);
          dec(top);
        until s[top+1]=x;
      end;
  end;

procedure work;
  var i,k:longint;

  begin
    fillchar(vis,sizeof(vis),false);
    fillchar(inner,sizeof(inner),false);
    top:=0;
    time:=0;
    count:=0;
    fillchar(dfn,sizeof(dfn),0);
    for i:=1 to n do
      if dfn[i]=0 then begin vis[i]:=true; tarjan(i); end;
    fillchar(oud,sizeof(oud),0);
    for i:=1 to n do
      begin
        k:=head[i];
        while k<>0 do
          begin
            if f[i]<>f[edge[k].p] then inc(oud[f[i]]);
            k:=edge[k].link;
          end;
      end;
  end;

procedure print;
  var i,t,v:longint;

  begin
    t:=0;
    for i:=1 to count do
      if oud[i]=0 then begin inc(t); v:=i; end;
    if t=1 then writeln(c[v]) else writeln(0);
  end;

begin
  init;
  work;
  print;
end.

Followed by:

Post your reply here:
User ID:
Password:
Title:

Content:

Home Page   Go Back  To top


All Rights Reserved 2003-2013 Ying Fuchen,Xu Pengcheng,Xie Di
Any problem, Please Contact Administrator