题意:给出一个无向图,计算去掉一个点后所能得到的最大块数
分析:dfs求出连通块的数量tot和删除每个点后能把该点所在的块分割成的块的数量s[i],那么ans就是最大的sum-s[i](我代码里的s[i]表示删除每个点后能把该点所在的块分割成的块的数量-1)
代码:
var n,m,e,t:longint; dfn,low,last,s:array[1..10000] of longint; side:array[1..40000] of record x,y,next:longint; end; procedure add(x,y:longint); begin inc(e); side[e].x:=x; side[e].y:=y; side[e].next:=last[x]; last[x]:=e; inc(e); side[e].x:=y; side[e].y:=x; side[e].next:=last[y]; last[y]:=e; end; procedure init; var i,x,y:longint; begin e:=0; fillchar(last,sizeof(last),0); for i:=1 to m do begin readln(x,y); add(x+1,y+1); end; end; function min(x,y:longint):longint; begin if x<y then exit(x) else exit(y); end; procedure dfs(x:longint); var i:longint; begin inc(t); dfn[x]:=t; low[x]:=t; i:=last[x]; while i>0 do with side[i] do begin if dfn[y]=0 then begin dfs(y); low[x]:=min(low[x],low[y]); if low[y]>=dfn[x] then inc(s[x]); end else low[x]:=min(low[x],dfn[y]); i:=next; end; end; procedure main; var ans,tot,i:longint; begin fillchar(dfn,sizeof(dfn),0); fillchar(low,sizeof(low),0); fillchar(s,sizeof(s),0); tot:=0; t:=0; for i:=1 to n do if dfn[i]=0 then begin inc(tot); dfs(i); dec(s[i]); end; ans:=0; for i:=1 to n do if tot+s[i]>ans then ans:=tot+s[i]; writeln(ans); end; begin readln(n,m); while n+m>0 do begin init; main; readln(n,m); end; end.