toj 1026/2189 Network 求割点数量

题意:一个公司有一个网络,连接着从编号1到N共N个地方,然后给出一些边,表示哪两个地方相连。有些点一旦断开所有和它关联的边,那么图不再联通,称这样的点为“critical  place”,求有多少个这样的点。


分析:直接用dfs求割点数量就好了。


代码:

var
  e,t,s,n:longint;
  side:array[1..20000] of record
    x,y,next:longint;
  end;
  v:array[1..100] of boolean;
  last,low,dfn:array[1..100] of longint;

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
  x,y:longint;
begin
  e:=0;
  fillchar(last,sizeof(last),0);
  read(x);
  while x>0 do
  begin
    while not eoln do
    begin
      read(y);
      add(x,y);
    end;
    readln;
    read(x);
  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
               if x=1 then inc(s);
               dfs(y);
               low[x]:=min(low[x],low[y]);
               if low[y]>=dfn[x] then v[x]:=true;
             end
        else low[x]:=min(low[x],dfn[y]);
      i:=next;
    end;
end;

procedure print;
var
  ans,i:longint;
begin
  ans:=0;
  if s>1
    then v[1]:=true
    else v[1]:=false;
  for i:=1 to n do
    if v[i] then inc(ans);
  writeln(ans);
end;

procedure main;
begin
  fillchar(low,sizeof(low),0);
  fillchar(dfn,sizeof(dfn),0);
  fillchar(v,sizeof(v),false);
  s:=0;
  t:=0;
  dfs(1);
end;

begin
  readln(n);
  while n>0 do
  begin
    init;
    main;
    print;
    readln(n);
  end;
end.


你可能感兴趣的:(toj 1026/2189 Network 求割点数量)