边双连通有一个非常简单的做法就是先找出所有桥,然后再dfs一次不走桥即可
答案是(叶子节点的个数+1)/2
1 type node=record 2 next,po:longint; 3 end; 4 5 var e:array[0..20010] of node; 6 p,dfn,low,d,be,fa:array[0..5000] of longint; 7 hash:array[0..5000,0..5000] of boolean; 8 b:array[0..20010] of boolean; 9 len,n,m,x,y,i,ans,t,s,j,h,r:longint; 10 11 function min(a,b:longint):longint; 12 begin 13 if a>b then exit(b) else exit(a); 14 end; 15 16 procedure add(x,y:longint); 17 begin 18 hash[x,y]:=true; 19 inc(len); 20 e[len].po:=y; 21 e[len].next:=p[x]; 22 p[x]:=len; 23 end; 24 25 procedure tarjan(x:longint); 26 var i,y:longint; 27 begin 28 inc(h); 29 dfn[x]:=h; 30 low[x]:=h; 31 i:=p[x]; 32 while i<>-1 do 33 begin 34 y:=e[i].po; 35 if y<>fa[x] then 36 begin 37 if dfn[y]=0 then 38 begin 39 fa[y]:=x; 40 tarjan(y); 41 end; 42 low[x]:=min(low[x],low[y]); 43 if low[y]>dfn[x] then 44 begin 45 b[i]:=true; 46 b[i xor 1]:=true; 47 end; 48 end; 49 i:=e[i].next; 50 end; 51 end; 52 53 procedure dfs(x:longint); 54 var i,y:longint; 55 begin 56 be[x]:=s; 57 i:=p[x]; 58 while i<>-1 do 59 begin 60 y:=e[i].po; 61 if (be[y]=0) and not b[i] then dfs(y); 62 if b[i] and (be[x]<>be[y]) then inc(d[be[x]]); 63 i:=e[i].next; 64 end; 65 end; 66 67 begin 68 len:=-1; 69 fillchar(p,sizeof(p),255); 70 readln(n,m); 71 for i:=1 to m do 72 begin 73 readln(x,y); 74 if not hash[x,y] then 75 begin 76 add(x,y); 77 add(y,x); 78 end; 79 end; 80 tarjan(1); 81 for i:=1 to n do 82 if be[i]=0 then 83 begin 84 inc(s); 85 dfs(i); 86 end; 87 88 for i:=1 to s do 89 if d[i]=1 then inc(ans); 90 writeln((ans+1) shr 1); 91 end.