toj 2299 Electricity 求无向图割点

题意:给出一个无向图,计算去掉一个点后所能得到的最大块数


分析: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.


你可能感兴趣的:(toj 2299 Electricity 求无向图割点)