CF1149D放棄道路(最短グラフ理論、非圧縮状態、最小スパニングツリー)

タイトル効果:$ N $点は、2つだけの右側図の縁への$ Mは$、$ A $は、$ B $に対する大きい、小さいはありません。

各点$ pが$の場合、すべての最小スパニングツリーこの図を尋ねる。、$ 1 $に$ pが$の最短距離の最小値を。

10 ^ 7 $ \ <B \ 200.1 \ $ 2 \ N \ 70.1 \ M。


本当に素晴らしい、ああ素晴らしいです。

右側は、$ $を光側と呼ばれているといい、いくつかの結論:(以下がありますが、$ bは$のための右側は、複数のエッジと呼ばれています)

結論1:2つだけ元のパス光側に点がある場合、これら2つの重い側経路上のすべての最小スパニングツリーではありません。最小スパニングツリーの性質に応じて、明らかに正しいです。

結論2:すべての重い側を削除し、元の場合は、China Unicom社は、数ブロックのままになります。パスは、それが戻って他のブロックに次にユニコムユニコムブロックを残してない場合にのみ、最小スパニングツリー上にあってもよいです。また、1の結論に基づいています。

あなたは、条件$ Fを設計することができ、[S] [U] $、$ S $はセットは、$ U $のポイントが現在位置している、リンクブロックを残しています。

原因の$ F [S] [U] $は$ fに転送することができる[S] [V] $、$のF [S] [V] $を使用ので、$ Fを[S] [U] $に転送することができます最短の方法を更新します。

時間複雑$ O(2 ^ nmの\ログ(2 ^ NM))$。実際には、2つだけ右エッジがあるので、あなたは2つのキュー、1ポイントが最も2回更新さを開始することができ、複雑さは$ O(2 ^ NM)$です。

しかし、別の結論があります:

結論3:ブロックサイズは、リンク$ \ル3 $であれば、それは$ S $のこのリンクブロックを考える必要はありません。証明、光のないつ以上の内側の縁のクロスでブロックサイズユニコム$ \ル3 $時間を少なくとも二つのヘビーエッジをブロックするためにバックリンクを残し、そしてとき以来。だから、記録されていない場合でも、最適な戦略は、このブロックに中国聯通のリターンを残していないだろう。

そして、唯一のレコードサイズ$ \ GEユニコムは$ 4ブロックします。時間複雑さの$ O(2 ^ {N / 4} M)$。

もう少し詳しく。

#include <ビット/ STDC ++ H>
 使用して 名前空間STDを、
#define <;(私は++ =(B)(I、B)iは=(A)INT)用のため
 の#define ROF(I、B)(I =(A)がINTのための; I => (B); i--)
 の#define MEM(X、V)のmemset(X、V、はsizeof(x))を
インラインINT 読み出す(){
     CHAR CH = GETCHAR()。INT X = 0、F = 0 一方、(CH < ' 0 ' || CH> ' 9 ')は、f | = CH == ' - '、CH = GETCHAR()。
    一方、(CH> = ' 0 ' && CH <' 9 ')、X = X * 10 + CH- ' 0 '、CH = GETCHAR()。
    リターン?F - X:X; 
} 
int型、w nが、M、A、Bを、[ 77 ] [ 77 ]、ID [ 18 ]、CNT、TMP、F [ 20000000 ]、Q [ 20000000 ]、Q2 [ 20000000 ]、H1、R1、H2、R2。
BOOL VIS1 [ 77 ]、VIS2 [ 77 ]。
INT DFS1(INT U){ 
    VIS1 [U] = int型 S = 1 ; 
    (I FOR、1、n)の場合(W [U] [I] == A && VIS1 [I])S + =!DFS1(I)。
    リターン秒; 
} 
ボイド DFS2(int型 U、int型のC){ 
    VIS2 [U] = 
    ID [U] =のC。
    (I、FOR 1、n)の場合(W [U] [I] == A &&!VIS2 [i])とDFS2(I、C)。
} 
インラインINT(AT int型のx、int型の Y){ リターンのx * N + Y- 1 ;}
 int型のmain(){ 
    N =(リード)、M =読み取る(); =読み取る(); B = 読み取ります() ;
    (I、FOR 1 、M){
         int型、U =読み取る()、V = 読み取ります(); 
        W [U] [V] = [V] [U]は= W 読み出します(); 
    } 
    (I、FOR 1、N)であれば(VIS1 [I]!)であれば(DFS1(I)> = 4)DFS2(I、++ CNT)。
    TMP = CNT; 
    MEM(VIS1、0 ); 
    (I、FOR 1、N)であれば(VIS1 [I]!)であれば(DFS1(I)< 4)DFS2(I、++ CNT)。
    MEM(F、から0x7f )。
    F [において(01)] = 0; 
    Q1 [H1= R1 = 1 ] =で(01); Q2は[H2 = R2 = 1 ]で=(01 )。
    一方、(H1 <= R1 || H2 <= R2){
         int型、U。
        もし(H1> R1)U = Q2 [H2 ++ ]。
        そう であれば(H2> R2)U = Q1 [H1 ++ ]。
        そう であれば(F [Q1 [H1] <F [Q2 [H2])U = Q1 [H1 ++ ]。
        のu = Q2 [H2 ++ ];
        INT X = U / N、Y = U%N + 1 
        (I、FOR 1 、N){
             場合(!W [Y] [I] ||(ID [i]が<= TMP &&(X&(1<<(ID [I] - 1))))|| (ID [I] == ID [Y] && W [Y] [I] == B))続けますint型のV;
            もし(!ID [Y] <= TMP && ID [Y] = ID [i])とV =で(X |(1 <<(ID [Y] - 1 ))、I)。
            他に、V = (X、i)における、
            もし(F [V]> F [U] + W [Y] [I]){ 
                F [V] = F [U] + W [Y] [I]。
                もし(W [Y] [I] == A)Q1 [++ R1] = V。
                他の Q2 [++ R2] = V; 
            } 
        } 
    } 
    FOR(I、1 、N){
         int型 ANS =2E9; 
        FOR(j、0、(1 << TMP) - 1)ANS = 分(ANS、F [(J、I)で])。
        printf(" %dの" 、ANS)。
    } 
}
コードの表示

 

おすすめ

転載: www.cnblogs.com/1000Suns/p/11073185.html