POJ 3352

POJ 3352

题目大意:一幅图,至少加多少条边后,使得任意断开一条边都不会把图分裂成两部分。

解:求双连通分支的数量,就是把所有边双连通分量缩点,构树,答案为叶节点数目+1 >> 1;(证略)

备注:有很二的地方,缩点统计想关于同一个双连通分量多次指向另一个双连通分量怎么办= 。=,明明叫双连通分量,怎么会有多条边连向其他分量呢?如果是他们也合并成一个双连通分量了。

View Code
  1 //poj 3352
2 const
3 maxn=1111;
4 maxm=1111;
5 type
6 data=record
7 next, dest, op: longint;
8 end;
9 var
10 edge: array[1..maxn*2]of data;
11 deg, pre, dist, low, dfn, vect: array[1..maxn]of longint;
12 visit: array[1..maxn]of boolean;
13 time, stot, ans, tot, n, m: longint;
14 procedure add(x, y: longint);
15 begin
16 inc(tot);
17 with edge[tot] do begin
18 dest := y;
19 next := vect[x];
20 vect[x] := tot;
21 op := tot + 1;
22 end;
23 inc(tot);
24 with edge[tot] do begin
25 dest := x;
26 next := vect[y];
27 vect[y] := tot;
28 op := tot - 1;
29 end;
30 end;
31
32 procedure init;
33 var
34 i, j, x, y: longint;
35 begin
36 ans := 0; tot := 0;
37 fillchar(vect, sizeof(vect), 0);
38 readln(n, m);
39 for i := 1 to m do begin
40 readln(x, y);
41 add(x, y);
42 end;
43 end;
44
45 procedure tarjan(x: longint);
46 var
47 i: longint;
48 begin
49 inc(time);
50 low[x] := time; dfn[x] := time;
51 visit[x] := true;
52 i := vect[x];
53 while i<>0 do
54 with edge[i] do begin
55 if pre[x]<>dest then
56 if dfn[dest]=0 then begin
57 pre[dest] := x;
58 tarjan(dest);
59 pre[dest] := 0;
60 if low[dest]<low[x] then low[x] := low[dest];
61 end
62 else if visit[dest] then begin
63 if dfn[dest]<low[x] then low[x] := dfn[dest];
64 end;
65 i := next;
66 end;
67 visit[x] := false;
68 end;
69
70 procedure main;
71 var
72 i, u: longint;
73 begin
74 fillchar(dfn, sizeof(dfn), 0);
75 fillchar(visit, sizeof(visit), 0);
76 time := 0; stot := 0;
77 for i := 1 to n do
78 if dfn[i]=0 then tarjan(i);
79 fillchar(deg, sizeof(deg), 0);
80 for u := 1 to n do begin
81 i := vect[u];
82 while i<>0 do
83 with edge[i] do begin
84 if low[u]<>low[dest] then begin
85 inc(deg[low[u]]);
86 inc(deg[low[dest]]);
87 end;
88 i := next;
89 end;
90 end;
91 for i := 1 to maxn do
92 if deg[i] >> 1 = 1 then inc(ans);
93 if ans=1 then ans := 0;
94 ans := (ans+1)>>1;
95 end;
96
97 procedure print;
98 begin
99 writeln(ans);
100 end;
101
102 begin
103 assign(input,'1.txt'); reset(input);
104 init;
105 main;
106 print;
107 end.



posted @ 2012-04-06 19:53  F.D.His.D  阅读(181)  评论(0编辑  收藏  举报