[Poj]2186——强连通分量

[题目大意]
  • 给定有向G=(V,E)求所有点都可达的点的个数

[分析题解]
  •  这几天真是狠狠的钻研了不少的图论和数论,当然事实证明完全被数论虐成傻子了。
  • 显然是一个强连通分量的问题,对原图求强连通分量,然后统计新图中没有出度的点,如果只有一个,输出其包含原图中点的个数,否则输出0

[个人代码]
View Code
  1 //10180085        perseawe        2186    Accepted        1424K   79MS    Pascal  2645B   2012-05-10 19:54:27
  2 
  3 Var
  4   n,m,tot,NumofBlocks,Time,Top:Longint;
  5   dfn,low,hv,Faim,Stack:Array [0..10000+100of Longint;
  6   Vis,InStack:Array [0..10000+100of Boolean;
  7   Edge:Array [0..50000+500of Record wh,next:Longint;end;
  8 
  9 Procedure AddEdge(u,v:Longint);
 10   begin
 11     inc(tot);
 12     Edge[tot].next:=hv[u];hv[u]:=tot;
 13     Edge[tot].wh:=v;
 14   end;
 15 
 16 Procedure Init;
 17   var
 18     i,u,v:Longint;
 19   begin
 20     readln(n,m);
 21     tot:=0;Fillchar(Hv,Sizeof(Hv),0);
 22     for i:=1 to m do
 23       begin
 24         readln(u,v);
 25         AddEdge(u,v);
 26       end;
 27   end;
 28 
 29 Function Min(a,b:Longint):Longint;begin if a<b then exit(a);exit(b);end;
 30 
 31 Procedure TarJan(u:Longint);
 32   var
 33     v,tnode:Longint;
 34   begin
 35     inc(Time);
 36     dfn[u]:=Time;low[u]:=Time;vis[u]:=True;
 37     inc(top);Stack[top]:=u;InStack[u]:=True;
 38     tnode:=hv[u];
 39     while tnode<>0 do
 40       begin
 41         v:=Edge[tnode].wh;
 42         if not(Vis[v]) then//树枝边,Min取Low
 43           begin
 44             tarJan(v);
 45             Low[u]:=Min(Low[u],Low[v]);
 46           end
 47         else
 48           if InStack[u] then Low[u]:=Min(Low[u],Dfn[v]);//后向弧,Low和Dfn
 49         tnode:=Edge[tnode].next;
 50       end;
 51     if Dfn[u]=Low[u] then//找到一个分支,下面是弹栈+标记的过程
 52       begin
 53         Inc(NumOfBlocks);
 54         Repeat
 55           v:=Stack[top];
 56           Faim[v]:=NumOfBlocks;
 57           InStack[v]:=False;
 58           Dec(top);
 59         Until u=v;
 60       end;
 61   end;
 62 
 63 Procedure Main;
 64   var I:longint;
 65 
 66   begin
 67     Fillchar(vis,Sizeof(vis),False);
 68     Fillchar(InStack,Sizeof(InStack),False);
 69     Fillchar(Dfn,Sizeof(Dfn),0);
 70 
 71     top:=0;NumOfBlocks:=0;
 72     For I:=1 to N do
 73       if Not(Vis[I]) then
 74         TarJan(I);
 75     {$IFDEF LD}
 76     For I:=1 to N do writeln(I,'  Aim to  ',Faim[I]);
 77     {$ENDIF}
 78 
 79   end;
 80 
 81 Procedure Print;
 82   var
 83     I,tmp,ans,u,v,tnode:Longint;
 84   begin
 85     Fillchar(Dfn,sizeof(Dfn),0);
 86     For I:=1 to N do
 87       begin
 88         tnode:=hv[I];u:=Faim[I];
 89         While tnode<>0 do
 90           begin
 91             v:=Faim[Edge[tnode].wh];
 92             if u<>v then Inc(dfn[u]);//如果不在一个强连通分治中
 93             tnode:=Edge[tnode].next;
 94           end;
 95       end;
 96     tmp:=0;
 97     For I:=1 to NumOfBlocks do
 98       if Dfn[I]=0 then begin Inc(tmp);ans:=I;end;
 99     if tmp>1 then begin writeln(0);Halt;end;
100     tmp:=ans;ans:=0;
101     For I:=1 to N do if Faim[I]=tmp then Inc(ans);
102     writeln(ans);
103   end;
104 
105 Begin
106   {$IFDEF LD}
107   Assign(INPUT,'P2186.in');Reset(INPUT);
108   //Assign(OUTPUT,'P2186.out');Rewrite(OUTPUT);
109   {$ENDIF}
110 
111   Init;
112   Main;
113   Print;
114 
115   {$IFDEF LD}
116   Close(INPUT);Close(OUTPUT);
117   {$ENDIF}
118 End.

[相关链接] 
  1. http://hi.baidu.com/lydrainbowcat/blog/item/42a6862489c98820c89559f3.html

[启发总结]
  1.  挺厉害的,1A!
posted @ 2012-05-10 20:07  PerSeAwe  阅读(224)  评论(0编辑  收藏  举报