ネットワークUVA - 315(図通信要求カット点)

する#include <stdio.hに> 
する#include <アルゴリズム> 
の#include <iostreamの> 
する#include < 文字列・H>
 使用して 名前空間STD; 

/ * 
*切削点への要求と、図のブリッジ
*カットポイントを見つけることができないとブリッジは、シークブロック通信削除各点が増加した後。
*重いエッジの処理は、第1の行列を格納することができることを、隣接するサブテーブル、または再調停注
* / 
CONST  INT MAXN = 10010 ;
 のconst  int型 MAXM = 100010 ;
 構造体のエッジ
{ 
    INT に、次に、
     BOOL切り取り; // かどうかのフラグブリッジ
}エッジ[MAXM];
 int型のヘッド[MAXN]、TOT、
 INT低[MAXN]、DFN [MAXN]、スタック[MAXN];
 int型、インデックス、トップ
 BOOL Instack [MAXN];
 BOOL カット[MAXN];
 int型 add_block [MAXN]; //は、通信ポイントブロック取り除いた後に追加
int型の橋を; 

ボイド addedge(INT U、int型V)
{ 
    エッジ[TOT] .TO = V、エッジ[TOT】ヘッド.next = [U]、エッジ[TOT = .cut falseに
    ヘッド[U] = TOT ++ ; 
} 


ボイド Tarjan(INT U、INT PRE)
{ 
    int型のV; 
    低[U] = DFN [U] ++ = ++] =ランキング;
    スタック[トップU; 
    Instack [U] = int型の息子= 0 ;
    以下のためにint型 - ;!I = I =ヘッド[U] 1 ; I = エッジ[I] .next)
    { 
        V = エッジ[I] .TO。
        もし(V ==前)続けますもし(!DFN [V])
        { 
            息子 ++ ; 
            Tarjan(V、U); 
            もし(低[U]>低[V])低[U] = 低[V]。
            // //無向エッジと場合にのみ、(u、v)は側枝であり、そしてDFS(U)<低を満たす場合には(u、v)は、ブリッジである(V )。
            IF(低[V]> DFN [U])
            {  ++ 
                エッジ[I] .cut = trueに
                エッジ[I ^ 1 ] = .cut 真に; 
            } 
            // カットポイント
             // 頂点uがカットポイントであります満足場合にのみ(1)又は(2)(1)Uがルートであり、uは、複数のサブツリーを有します。
            @ (2)Uは(U、V)側枝(または親子エッジの存在満たし、ルートでない
             // このようなDFS(U)<=低いこと、即ち、U及び探索木におけるV父) (V)
            IF(U!&&事前=低[V]> = DFN [U])// ないルート
            { 
                切り取り[U]= 
                add_block [U] ++ ; 
            } 
        } 
        そう であれば(低[U]> DFN [V])
            低[U] = DFN [V]。
    } 
    // 树根、分支数大于1 
    た場合(Uは==事前&&息子> 1)= [U]を切断もし(U == PRE)add_block [U] =息子- 1 
    Instack [U] = 
    トップ - ; 
} 

ボイドが解決する(INTのN)
{ 
    memsetの(DFN、0はsizeof (DFN))。
    memsetの(Instack、はsizeof (Instack)); 
    memset(add_block、0はsizeof (add_block))。
    memsetの(カット、はsizeof (カット)); 
    インデックス =トップ= 0 ; 
    ブリッジ = 0 以下のためにint型 I = 1 ; N =私は<;私は++ の場合(!DFN [i])と
            Tarjan(I、I); 
    int型 ANS = 0 ;
    以下のためにint型 I = 1 = iが<Nを;私++場合(切断[i])と
            ANS ++ 
    printf(" %d個の\ n " 、ANS)。
} 
ボイドのinit()
{ 
    TOT = 0 
    memsetの(頭、 - 1はsizeof (ヘッド))。
} 

int型のmain()
{ 
    int型N;
    一方、(scanf関数(" %のD "、&n)は、N)
    { 

        int型、B、。
        char型のCH; 
        その中に(); 
        しばらく(scanf関数(" %dの "、&​​A )、A)
        { 
            一方(のscanf(" %d個の%のC "、&​​B、&CH))
            { 
                addedge(B)
                addedge(B、A)。
                もし(CH == ' \ n個' ブレーク
            } 
        } 
        (n)を解きます。
    } 
    戻り 0 
}

 

おすすめ

転載: www.cnblogs.com/smallhester/p/11259383.html