最短経路、ダイクストラ、SPFA - hdu1535

トピックリンク

トレーニング先輩はそう突然のすべてがSPFAが練習していなかったので、この特別なカードSPFAのタイトルトラックは考えを持っていない、ダイクストラがした使用、今日負タイトルリングを与えていません

タイトルの意味

点1への最短距離とが、別の点との最短距離を求めます

トピック分析

両方の行がSPFAはべき別の点との最短距離、すなわち、シングルソースの最短経路を求め、そしてダイクストラ

両方向の経路の長さが同じではないので、点までの最短距離、他方は、実際には、そう逆成果と同様に、他の点からの距離を見つけることであるが、

トピックコード

書式#include <iostreamの> 
書式#include <stdio.hに> 
する#include < 文字列の.h> 
の#include <キュー>
 使用して 名前空間はstdを、
const  int型 MAXN = 1E6 + 7 const  int型 INF = 0x3f3f3f3f 
typedefの長い 長いLL。
int型のヘッドは、[MAXN]、[MAXN] DIS;
INTのTOT、U [MAXN]、V [MAXN]、[MAXN] W。
BOOL VIS [MAXN]。
ANS LL; 
int型、T、N、M。
構造体の縁{
     INT 、次に、Wに対して、
} E [MAXN]。
構造体ノード{
    int型のPOS、DIS;
    ブール 演算子 <(constのノード&X)のconst {
         戻り DIS> x.disと、
    } 
}。
ボイド追加(INT U、INT V、INT W){ 
    E [TOT] .TO = V。
    E [TOT] .W = W。
    E [TOT] .next = 頭部[U]。
    ヘッド[U]は ++ TOTを= 
} 
ボイドのinit(){ 
    TOT = 0 
    memset(DIS、INF、はsizeof (DIS))。
    memsetの(頭、- 1はsizeof (ヘッド))。
    memsetの(VIS、はsizeof (VIS)); 
} 
ボイドダイクストラ(){ 
    DIS [ 1 ] = 0 
    PRIORITY_QUEUE <ノード> Q。
    q.push((ノード){ 10 })。
    一方、(!q.empty()){ 
        ノードTEMP = q.top(); q.pop()。
        int型のu = temp.pos。
        もし(VIS [U])続けます
        VIS [U] = ;
        にとってint型 - ;!I = I =ヘッド[U] 1 ; I = {E [I] .next)
             int型、V = E [I] .TO。
            もし(DIS [V]> DIS [U] + E [i]は.W){ 
                DIS [V] = DIS [U] + E [I] .W。
                もし(!VIS [V])q.push((ノード){V、DIS [V]})。
            } 
        } 
    } 
} 
int型のmain(){ 
    scanf関数(" %のD "、&T)。
    一方、(t-- ){ 
        scanf関数(" %D%dの"、&​​N、&M)。
        ANS = 0; 
        その中に(); 
        以下のためにint型 I = 1 ; I <= M; iは++ ){ 
            scanf関数(" %D%D%D "、およびU [i]は、&​​V [i]は、&W [I])。
            ;(W [i]は、U [i]は、V [I])を追加 
        } 
        ダイクストラ()。
        以下のためにint型 I = 2 ; iが<= N; iは++ 
            ANS + = DIS [i]は、
        その中に(); 
        int型 I = 1 ; I <= M; iが++ ){ 
            ([I]、U [i]は、[I] W V)を加えます。
        } 
        ダイクストラ()。
        以下のためのint型I = 2 ; iは= <N; iは++ 
            ANS + = DIS [i]は、
        printf(" %LLDする\ n " 、ANS)。
    } 
    戻り 0 
}
ダイクストラの練習

ダイクストラが本当に多くを行う、再び通り過ぎます

書式#include <iostreamの> 
書式#include <stdio.hに> 
する#include < 文字列の.h> 
の#include <キュー>
 使用して 名前空間はstdを、
const  int型 MAXN = 1E6 + 7 const  int型 INF = 0x3f3f3f3f 
typedefの長い 長いLL。
int型のヘッドは、[MAXN]、[MAXN] [MAXN]、numはDIS;
BOOL VIS [MAXN]。
ANS LL; 
int型、T、N、M、TOT、U [MAXN]、V [MAXN]、[MAXN] W。
構造体の縁{
     INT 、次に、Wに対して、
} E [MAXN]。
無効アドオン(int型のuを、int型 V、INT W){ 
    E [TOT] .TO = V。
    E [TOT] .W = W。
    E [TOT] .next = 頭部[U]。
    ヘッド[U]は ++ TOTを= 
} 
ボイドのinit(){ 
    TOT = 0 
    memsetの(頭、 - 1はsizeof (ヘッド))。
    memsetの(VIS、はsizeof (VIS)); 
    memset(DIS、INF、はsizeof (DIS))。
    memset(NUM、0はsizeof (NUM))。
} 
BOOL SPFA(){ 
    キュー< 整数 > Q; 
    DIS [ 1 ] = 0 ; numが[ 1 ] ++; VIS [ 1 ] = 
    q.push(1 )。
    一方、(!q.empty()){
         int型、U = q.front(); q.pop()。
        VIS [U] = ;
        以下のためにint型 - ;!I = I =ヘッド[U] 1 ; I = {E [I] .next)
             int型、V = E [I] .TO。
            もし(DIS [V]> DIS [U] + E [I] .W){ 
                DIS [V] = DIS [U] +E [i]は.W。
                もし(!VIS [V]){ 
                    VIS [V] = ; 
                    NUM [V] ++ ; 
                    q.push(V); 
                    もし(numは[V]> n)を返し 
                } 
            } 
        } 
    } 
    戻り 
} 
int型のmain(){ 
    scanf関数(" %のD "、&T)。
    一方、(t-- ){ 
        scanf関数(" %d個の%のD "、&​​N、& M)。
        ANS = 0 ; 
        その中に(); 
        以下のためにint型 I = 1 ; I <= M; iは++ ){ 
            scanf関数(" %D%D%D "、およびU [i]は、&​​V [i]は、&W [I])。
            ;(W [i]は、U [i]は、V [I])を追加 
        } 
        SPFA()。
        以下のためにint型 I = 2 ; iが<= N; iは++ 
            ANS + = DIS [i]は、
        その中に(); 
        int型 I = 1 ; I <= M; iが++ ){ 
            ([I]、U [i]は、[I] W V)を加えます。
        } 
        SPFA()。
        にとって int型I = 2 ; iは= <N; iは++ 
            ANS + = DIS [i]は、
        printf(" %LLDする\ n " 、ANS)。
    } 
    戻り 0 
}
SPFA練習

私は実際に書くためにテンプレートに従って、未熟練を書きました

私は再び考えています

 

おすすめ

転載: www.cnblogs.com/helman/p/11278463.html