边双连通有一个非常简单的做法就是先找出所有桥,然后再dfs一次不走桥即可
答案是(叶子节点的个数+1)/21 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 begin13 if a>b then exit(b) else exit(a);14 end;15 16 procedure add(x,y:longint);17 begin18 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 begin28 inc(h);29 dfn[x]:=h;30 low[x]:=h;31 i:=p[x];32 while i<>-1 do33 begin34 y:=e[i].po;35 if y<>fa[x] then36 begin37 if dfn[y]=0 then38 begin39 fa[y]:=x;40 tarjan(y);41 end;42 low[x]:=min(low[x],low[y]);43 if low[y]>dfn[x] then44 begin45 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 begin56 be[x]:=s;57 i:=p[x];58 while i<>-1 do59 begin60 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 begin68 len:=-1;69 fillchar(p,sizeof(p),255);70 readln(n,m);71 for i:=1 to m do72 begin73 readln(x,y);74 if not hash[x,y] then75 begin76 add(x,y);77 add(y,x);78 end;79 end;80 tarjan(1);81 for i:=1 to n do82 if be[i]=0 then83 begin84 inc(s);85 dfs(i);86 end;87 88 for i:=1 to s do89 if d[i]=1 then inc(ans);90 writeln((ans+1) shr 1);91 end.