トレーニング先輩はそう突然のすべてが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((ノード){ 1、0 })。 一方、(!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 。 }
私は実際に書くためにテンプレートに従って、未熟練を書きました
私は再び考えています