[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+100] of Longint;
6 Vis,InStack:Array [0..10000+100] of Boolean;
7 Edge:Array [0..50000+500] of 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.
2
3 Var
4 n,m,tot,NumofBlocks,Time,Top:Longint;
5 dfn,low,hv,Faim,Stack:Array [0..10000+100] of Longint;
6 Vis,InStack:Array [0..10000+100] of Boolean;
7 Edge:Array [0..50000+500] of 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.
[相关链接]
- http://hi.baidu.com/lydrainbowcat/blog/item/42a6862489c98820c89559f3.html
[启发总结]
- 挺厉害的,1A!
——————————————————————————————————————
你说,我们的存在,永不消逝。对吧?
如果,我们都在努力创造了存在。我们,会幸福的。对吧?