図の点を切断するいいえ切刃ありません。

定義:

  無向グラフG =(V、E)指定されました:

  x∈V後、関連する図面からすべてのエッジとノードXとノードXを削除し、Gは、二つのサブ図二つ以上の非接続に分割されている場合については、G xがあると呼ばれるカットポイント

  e∈E後、図のエッジEから省略、Gが2つの互いに素のサブグラフに分割される場合のために、G eは呼ばれるブリッジ又は刃先。

探しています:

  よく知られているコンピュータ科学者ロバート・タージャンによるとTarjanのアルゴリズムの名前(はい、LCAは、Tarjanのアルゴリズムがあること)、オンライン時間のブリッジにカット無向グラフのポイントを得ることができます。

  図のない深さ優先トラバーサルにTarjanアルゴリズム。

タイムスタンプ:

  マークのNを「と呼ばれる標識されたN個のノードに1の整数を与え初めて訪問される各ノードのための時系列、図の深さ優先トラバーサルのプロセスにタイムスタンプ」と呼ばれる[X] DFN 。

検索ツリー:

  必要に応じて図面深さ優先トラバーサル、一度だけ、各アクセスポイントに対して開始ノードが存在しないことです。ツリー再帰を構成する全てのエッジ(x、y)は、我々が「呼んで、(深さ優先トラバーサルがVIS [x]の配列タグが繰り返し歩行より縁側を防止するために使用されている)が発生無向グラフを検索しますツリー「もちろん、一般的に何も設定は(必ずしも通信において)各ブロックの通信の探索木の無向グラフ図ないし」森を検索します」。

遡及値:

  タイムスタンプに加えて、Tarjanアルゴリズムはまた、「導入遡及値を [x]がロー」。Xで表される提供サブツリー(X)は、ルートとするサブツリー内の探索木です。低[X]は最小タイムスタンプつのノードとして定義されます。

  1. サブツリー内のノード(X)。
  2. ない探索木のエッジを介して、ノード内のサブツリー(X)に到達することができる(検索ツリーは、探索木の端に接続されていないノードをルートXサブツリーです)。

  [X] =のDFN [X](論理ルートノードは、そのノードをルートタイムスタンプサブツリー内のタイムスタンプよりも小さい)、およびxの観点から、[X]、我々は最初のローに初期化され、低を算出しますすべての側面(x、y)を開始します。

  1. xがyの探索木、他の低親ノードである場合、[X] =分(低[Y]、[x]は低いです)。
  2. 側面がないわけではない探索木で、他の低[X] =分(低[x]は、DFN [Y])。

エッジ判定ルールを切断:

  無向エッジ(X、Y)は、カッティングエッジである場合、xはサブツリー探索ノードy、満たす場合にのみ:
                    DFNは、[X] <低[Y]

充足:  

  定義では、サブツリー(Y)からの指示[X] <低[Y] DFN、関係なく、そのエッジの下を前提エッジ(x、y)を介さないことなく、うまくアクセスノードよりもX X以前の手の届かないところに行きます後(に達した場合、値は> =のDFN [x]はトレースされるべきである)、すなわち、削除されたエッジ(x、y)は、サブツリー(Y)×無限に接続さで、無限が先Xよりアクセスノードに接続されています図は二つの部分に分割したので、(x、y)は、切断エッジです。

必要性:

  任意の子ノードxについて、[X]> =低[Y]をDFNた場合、各サブツリー(Y)の説明は、(その後、到着XまたはXより前にアクセスするために、Xを他のエッジノードをバイパスすることができy)は、天然に最先端されていません。

  また、カッティングエッジは、探索ツリーエッジである必要があり、そして単純なリングのエッジは、エッジを切断してはなりません。

  特に注目すべきは、我々はそれを介して行くようにすべての点xは、その親のFAへの総アクセスを有向グラフからので、何もありません。低い(X、FA)の探索木の計算方法の縁部、およびFAのXノードは子ではない、[X]タイムスタンプ低いFAを更新するために使用することができません。
  しかし、各ノードの親ノードのレコードだけが、複数のエッジの場合は処理できない場合-一方の側のxおよびFA、(X、FA)との間の複数のエッジの任意の切刃はありません。これらの反復側では、他のいくつかの「エッジ探索木」と考えるだけでは、ありません。複数のエッジ、DFN [FA]がある場合したがって、[X]をローに更新するために使用することができます。
  良い解決策は、「再帰的にノード番号のそれぞれの側に」変更レコード(これは重い側を扱うことができるツリー側FAを探索することによりアクセスを阻止します)。私たちは、これを達成するためのストレージ技術を「変換ペア」隣接リストを使用します。

コードを接続します。

1つの#include <ビット/ STDC ++ H>
 2  使用して 名前空間STDを、
3  のconst  int型 SIZE = 100010 4  int型のヘッド[SIZE]、版[ 2 *サイズ]、NXT [ 2 * SIZE]。
5  INT DFN [SIZE]、低[SIZE]、N、M、TOT、NUM。
6  ブールブリッジ[SIZE * 2 ]。
7  ボイド追加(int型のx、int型のY){
 8      版[++ TOT = Y、NXT [TOT =頭部[X]、ヘッドが[X] = TOTを、
9  }
 10  
11  空隙 tarjan(INTX、int型in_edge){
 12は      DFN [X] =低[X] ++ = NUMが//タイムスタンプの値に初期化トレース
 13である     ためint型 I =頭[X]を、I; I = NXT [I]){
 14          INT Y = 版[I];
 15          IF(!DFN [Y]){//探索木
 16              Tarjan(Y、I);
 17              低[X] = 分(低[X]、低[Y]) ;
 18は、             IF(低[Y]> DFN [X])
 。19                  ブリッジ[I] =橋[I ^ 。1 ] = trueに20である         }
 21が          IF!(I ^ = in_edge 。1){//探索木ではない
 22は              低[X] = 分(低[X]、DFN [Y]);
 23である         }
 24      } 
 25  }
 26である 
27  INT メイン(){
 28      CIN >> N- M;
 29      TOT = 1。;
 30      INT I = 1 ; I <= M; ++ I){
 31は         int型のX、Y、
 32          scanfの(" %のDの%のD "、およびX&Y);
 33である         追加(X、Y )、X)、(Yを追加 ; // エッジのペア格納しない
 34ことである     }
 35      のためにINT= I 1、I <= N; ++ I)//各無向グラフの通信ブロックの
 36          IF(DFN [I])Tarjan(I、!0 );
 37      のためのint型 I = 2 Iの<。 TOT; I + = 2 ){
 38が         IF (橋[I])
 39              のprintf(" %D%D \ N- "、版[I ^ 1 ]、版[I]);
 40      }
 41が     戻り 0 ;
 42れます }

ポイントカットの決定ルール:

  xは探索木(深さ優先トラバーサル起点)のルートノードではない場合、xはカット点があれば存在し、xはサブツリーサーチノードyである場合にのみ、満足である:
                  DFN [X] <=低[Y]

  具体的には、xは2つのつの子ノードの場合に限り、カッティングエッジの存在を満たすためのように、Xなものである、探索木のルートノードである場合。

  プルーフは、刃先と同様です。

  カットポイント決意ルール数が少ないので、カット点ため、要求は、親ノードと重い側、xが低いを更新するために使用することができる全ての点[X]から出発してタイムスタンプを考慮する必要がない場合。

コードを接続します。

1つの#include <ビット/ STDC ++ H>
 2  使用して 名前空間STDを、
3  のconst  int型 N = 20001、M = 100001 4  int型のヘッド[N]、版[ 2 *のM]、NXT [ 2 * M]。
5  int型DFN [N]、低[N]。
6  INTのN、M、TOT、NUM、ルート。
7  ブールカット[N]。
8  
9  ボイド追加(int型のx、int型のY){
 10      版[++ TOT = Y、NXT [TOT =頭部[X]、ヘッド[X] = TOT。
11  }
 12  
13 ボイド Tarjan(INT X){
 14      DFN [X] =低[X] ++ = NUM;
 15      int型フラグ=で0 ;
 16      用のint型 I =頭[X]を、I; I = NXT [I]){
 17          INT Y = 版[I];
 18である         IF(! {DFN [Y])
 19。             Tarjan(Y)
 20である              低[X] = 分(低[X]、低[Y]);
 21である             IF(低[Y] > = DFNは、[X]){
 22は、                  フラグに++ ; //ルートノード防止する場合である
 23は、                 IFフラグに(X =ルート||>!1。 24                     [X] =切断25              }
 26          } そうでなければ低[X] = 分(低[x]は、DFN [Y])。
27      }
 28  }
 29  
30  INT メイン(){
 31      のscanf(" %D%dの"、&​​N、&M)。
32      TOT = 1 33      のためにint型 = Iを1 ; I <= M; ++ I){
 34          、INT X、Y。
35          のscanf(" %D%dの"、およびX&Y)。
36         もし(x == y)を続けます37          、(x、y)を追加(Y、X)。
38      }
 39      のためのint型 i = 1 ; iは= N <; ++ I)
 40          かのルート=(DFN [I]!)I、tarjan(I)。
41      のためには、int型 i = 1 ; iは= N <; ++ I){
 42          であれば(カット[i])とCOUT << I << "  " 43      }
 44      リターン 0 45 }

 

おすすめ

転載: www.cnblogs.com/Asika3912333/p/11372797.html