[Tyvj1111 舞会]

[题目来源]:Tyvj P1111

[关键字]:有向图的连通分量

[题目大意]:给出一个图,求它的强连通分量数量

//============================================================================================================

[分析]:据说此题数据没有按有向图的强连通分量给,并查集就能过,但我还是用trajan做的(水题,练习一下)。tarjan算法和求无向图的割点、桥样子差不多,其本质也是一样的,利用dfs树和时间戳来判断,只不过比那两个算法多了一个栈,求图的连通性的还有floodfill算法求无向图的连通分量。

[代码]:

ContractedBlock.gif ExpandedBlockStart.gif View Code
 1 type
2 rec = record
3 y, n: longint;
4 end;
5 var
6 n, tot, ans, top, m: longint;
7 instack: array[0..300] of boolean;
8 stack: array[0..300] of longint;
9 dfn, lowlink, f: array[0..300] of longint;
10 e: array[0..5000] of rec;
11 link: array[0..300] of longint;
12
13 procedure make(x, y: longint);
14 begin
15 inc(m);
16 e[m].y := y;
17 e[m].n := link[x];
18 link[x] := m;
19 end;
20
21 procedure init;
22 var
23 i, y: longint;
24 begin
25 readln(n);
26 for i := 1 to n do
27 begin
28 read(y);
29 while y <> 0 do
30 begin
31 make(i,y);
32 read(y);
33 end;
34 end;
35 end;
36
37 function min(x, y: longint):longint;
38 begin
39 if x < y then exit(x) else exit(y);
40 end;
41
42 procedure tarjan(k: longint);
43 var
44 y, t: longint;
45 begin
46 inc(tot);
47 dfn[k] := tot;
48 lowlink[k] := tot;
49 instack[k] := true;
50 inc(top);
51 stack[top] := k;
52 t := link[k];
53 while t <> 0 do
54 begin
55 y := e[t].y;
56 if dfn[y] = 0 then
57 begin
58 tarjan(y);
59 lowlink[k] := min(lowlink[k],lowlink[y]);
60 end
61 else
62 if instack[y] then lowlink[k] := min(lowlink[k],dfn[y]);
63 t := e[t].n;
64 end;
65 if dfn[k] = lowlink[k] then
66 begin
67 inc(ans);
68 repeat
69 y := stack[top];
70 dec(top);
71 instack[y] := false;
72 f[y] := ans;
73 until k = y;
74 end;
75 end;
76
77 procedure work;
78 var
79 i: longint;
80 begin
81 tot := 0;
82 top := 0;
83 ans := 0;
84 fillchar(dfn,sizeof(dfn),0);
85 for i := 1 to n do
86 if dfn[i] = 0 then
87 tarjan(i);
88 writeln(ans);
89 end;
90
91 begin
92 init;
93 work;
94 end.



转载于:https://www.cnblogs.com/procedure2012/archive/2011/10/27/2226305.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值