poj3177 tarjan缩点+割边 模板 【pascal】

1、tarjan缩点求割边

2、缩点后此时一定形成一棵树,再把割边加回来求缩点后的各个点的度

3、至少在树上添加(leaf+1)/2 条边,就能 使树达到边二连通,leaf的度为1

var
        n,m,l,ans,a,b   :longint;
        time,top,p,q    :longint;
        vis             :array[0..10010] of boolean;
        low,dfn,z,belong:array[0..5010] of longint;
        indu            :array[0..10010] of longint;
        last            :array[0..5010] of longint;
        pre,other       :array[0..20010] of longint;
        ge              :array[0..20010] of boolean;
        i               :longint;
procedure connect(x,y:longint);
begin
   inc(l);
   pre[l]:=last[x];
   last[x]:=l;
   other[l]:=y;
end;

function min(a,b:longint):longint;
begin
   if a0) do
   begin
      p:=other[q];
      if dfn[p]=0 then
      begin
         dfs(p,x);
         low[x]:=min(low[x],low[p]);
         if low[p]>dfn[x] then
         begin
            ge[q]:=true;
            if (q mod 2=0) then ge[q-1]:=true
             else ge[q+1]:=true;
         end;
      end else
      if vis[p] and (p<>father) then low[x]:=min(low[x],dfn[p]);//
      q:=pre[q];
   end;
   //
   if (dfn[x]=low[x]) then
   begin
      cur:=-1;
      while (cur<>x) do
      begin
         cur:=z[top];
         dec(top);
         vis[cur]:=false;
         belong[cur]:=x+n;
      end;
   end;
end;

begin
   read(n,m);l:=0;ans:=0;
   for i:=1 to m do
   begin
      read(a,b);
      connect(a,b);
      connect(b,a);
   end;
   dfs(1,0);
   //
   fillchar(vis,sizeof(vis),false);
   for i:=1 to n do
   begin
      q:=last[i];
      while (q<>0) do
      begin
         if ge[q] then inc(indu[belong[i]]);
         q:=pre[q];
      end;
   end;
   //
   fillchar(vis,sizeof(vis),false);
   for i:=1 to n do
    if (indu[belong[i]]=1) and not vis[belong[i]] then
    begin
       inc(ans);vis[belong[i]]:=true;
    end;
   //
   ans:=(ans+1) div 2;
   writeln(ans);
end.
——by Eirlys

你可能感兴趣的:(tarjan,模板)