両面通信コンポーネントjarjan(POJ 3177)

効果:無向連結グラフを考えるとは、任意の2点(NO共通のエッジが、同じ中間頂点を通る)の間に少なくとも2つの独立した経路を作るために、少なくともプラス側の数を決定します。

考え一組に同じ連結成分内のすべての点がポイントとして見ることができる、収縮後、新しいツリーは、ツリーの図ブリッジ側が絵です。今に問題アルゴリズムトラヤヌスで、即ち、エッジの数は、(+ 1のノード番号の中程度の木)=追加/ 2「のエッジの最小数を追加するために、ツリーは、図通信がダブルエッジマップとなる可能」ダブルのUnicom社の部品

これはテンプレートです

1の#include <iostreamの>
 2の#include <cstdioを>
 3の#include < 文字列・H>
 4の#include <アルゴリズム>
 5の#include <キュー>
 6の#include <ベクトル>
 7  使って 名前空間STDを、
8  のconst  int型 MAXN = 1E4 + 10 9  構造体ノード
 10  {
 11      int型V、カット、NXT。
12 } G [ 2 * MAXN]。
13  int型のCNT;
14  int型ヘッド[MAXN]。
15  INT[MAXN]スタック。
16  INT ; MAXN] instack
17  INT 低[MAXN]、[MAXN] DFN。
18  INTが属する[MAXN]、デュ[MAXN]。
19  int型のブロックインデックス、
20  int型ブリッジ、トップ。
21  ボイドのinit()
 22  {
 23      、CNT = 0 24      のmemset(ヘッド、 - 1はsizeof (ヘッド))。
25  }
 26  ボイドビルド(INT U、INT V)
 27  {
 28      G [CNT] .V = V; G [CNT] .nxt =頭部[U]、G [CNT] .cut =0 ;頭部[U] = CNT ++ 29  }
 30  空隙 tarjan(INT U、INT PRE)
 31  {
 32      低[U] =のDFN [U] = ++ 指数;
33      スタック[トップ++] = U。
34      instack [U] = 1 35      INT V;
36      のためにint型 I =ヘッド[U]; I =! - 1 ; I = G [i]が.nxt){
 37          、V = G [I] .V。
38          であれば(前== V)続けます39          であれば(!DFN [V]){
40              tarjan(V、U)。
41              低[U] = 分(低[U]、[V]低いです)。
42              であれば(低[V]> DFN [U]){
 43                  ブリッジ++ 44                  G [i]が.cut = 1 45                  G [I ^ 1 ] .cut = 1 46              }
 47          }
 48          他の 場合(低[U]> [V] && instack DFN [V])にロー[U] =のDFN [V]。
49      }
 50      であれば(低[U] == DFN [U]){
 51          ブロック++ 52         実行{
 53              [ - V =スタックトップ]。
54              instack [V] = 0 ;
55              [V] =属するブロックを、
56          } 、一方(V =!U)。
57      }
 58  }
 59  ボイドが解決(int型N)
 60  {
 61      のint I、J。
62      int型のインデックス= 0 63      ブリッジ= 0 64      トップ= 0 65      ブロック= 0 66      のmemset(低、0はsizeof (低))。
67      のmemset(DFN、0はsizeof (DFN))。
68      のmemset(属し0はsizeof ()属します)。
69      のmemset(instack、0はsizeof (instack))。
70      tarjan(10 );
71      のためには、(i = 1 ; iが<= N; iは++ ){
 72          (J = 1、J =! - 1、J = G [J] .nxt){
 73              であれば(G [J] .cut)
74              デュ++ [[i]が属しています] 75          }
 76      }
 77      INT ANS = 0 78      のためには、(i = 1 ; iが=ブロックを<; iは++ ){
 79          であれば(DU [I] == 1 80の          ANS ++ 81      }
 82      のprintf(" %Dを\ n "、(ANS + 1)/ 2 )。
83  }
 84  のint main()の
 85  {
 86      int型N、M。
87      しばらく(〜のscanf(" %D%D "、&​​N、&M)){
 88          のinit();
89          のためにint型 I = 0 ;私がm <; Iは++ ){
 90              のint U、V。
91              のscanf(" %D%dの"、&​​U、およびV)。
92              ビルド(U、V);
93              ビルド(V、U);
94          }
 95          (n)を解きます。
96      }
 97      リターン 0 98 }

 

おすすめ

転載: www.cnblogs.com/pangbi/p/11755425.html