• 算法模板——Tarjan强连通分量


    功能:输入一个N个点,M条单向边的有向图,求出此图全部的强连通分量

    原理:tarjan算法(百度百科传送门),大致思想是时间戳与最近可追溯点

    这个玩意不仅仅是求强连通分量那么简单,而且对于一个有环的有向图可以有效的进行缩点(每个强连通分量缩成一个点),构成一个新的拓扑图(如BZOJ上Apio2009的那个ATM)(PS:注意考虑有些图中不能通过任意一个单独的点到达全部节点,所以不要以为直接tarjan(1)就了事了,还要来个for循环,不过实际上复杂度还是O(M),因为遍历过程中事实上每个边还是只会被走一次^_^)

     1 type
     2     point=^node;
     3     node=record
     4                g:longint;
     5                next:point;
     6     end;
     7 
     8 var
     9    i,j,k,l,m,n,h,t,ans:longint;
    10    ss,s:array[0..100000] of boolean;
    11    low,dfn,b,f:array[0..100000] of longint;
    12    a:array[0..100000] of point;
    13    p:point;
    14 function min(x,y:longint):longint;inline;
    15          begin
    16               if x<y then min:=x else min:=y;
    17          end;
    18 function max(x,y:longint):longint;inline;
    19          begin
    20               if x>y then max:=x else max:=y;
    21          end;
    22 procedure add(x,y:longint);inline;
    23           var p:point;
    24           begin
    25                new(p);
    26                p^.g:=y;
    27                p^.next:=a[x];
    28                a[x]:=p;
    29           end;
    30 procedure tarjan(x:longint);
    31           var i,j,k:longint;p:point;
    32           begin
    33                inc(h);low[x]:=h;dfn[x]:=h;
    34                inc(t);f[t]:=x;s[x]:=true;ss[x]:=true;
    35                p:=a[x];
    36                while p<>nil do
    37                      begin
    38                           if not(s[p^.g]) then
    39                              begin
    40                                   tarjan(p^.g);
    41                                   low[x]:=min(low[x],low[p^.g]);
    42                              end
    43                           else if ss[p^.g] then low[x]:=min(low[x],dfn[P^.g]);
    44                           p:=p^.next;
    45                      end;
    46                if low[x]=dfn[x] then
    47                   begin
    48                        inc(ans);
    49                        while f[t+1]<>x do
    50                              begin
    51                                   ss[f[t]]:=false;
    52                                   b[f[t]]:=ans;
    53                                   dec(t);
    54                              end;
    55                   end;
    56           end;
    57 begin
    58      readln(n,m);
    59      for i:=1 to n do a[i]:=nil;
    60      for i:=1 to m do
    61          begin
    62               readln(j,k);
    63               add(j,k);
    64          end;
    65      fillchar(s,sizeof(s),false);
    66      fillchar(ss,sizeof(ss),false);
    67      fillchar(f,sizeof(f),0);
    68      fillchar(low,sizeof(low),0);
    69      fillchar(dfn,sizeof(dfn),0);
    70      fillchar(b,sizeof(b),0);
    71      for i:=1 to n do
    72          if s[i]=false then tarjan(i);
    73      for i:=1 to n do a[i]:=nil;
    74      for i:=1 to n do add(b[i],i);
    75      for i:=1 to ans do
    76          begin
    77               p:=a[i];
    78               write('No. ',i,' :');
    79               while p<>nil do
    80                     begin
    81                          write(' ',p^.g);
    82                          p:=p^.next;
    83                     end;
    84               writeln;
    85          end;
    86      readln;
    87 end.
    88              
  • 相关阅读:
    ios tableviewcontroller
    jsp第十次作业
    jsp第九次作业
    jsp第八次作业
    jsp第七次作业
    jsp第六次作业
    jsp第五次作业
    jsp第四周作业-2
    jsp第四周作业-1
    软件测试第四周作业
  • 原文地址:https://www.cnblogs.com/HansBug/p/4271270.html
Copyright © 2020-2023  润新知