説明
与えられたn個の点、図双方向エッジストリップM。そこk個の点が重要です。各側は一定の長さを有します。
今は重要kは互いに通信を指すようにするように、マップを形成するために、エッジの一部を選択し、エッジ最小の長さを求めることができます。
入力
総行M + 2
行1:N、K、M、N点、K重要な点、Mエッジ;
Kポイントの2行目
M + 2は、ライン3を介して、各行は3つの数字、A、B、Cを含み、Cまでの長さをAからBへの双方向経路を表現しました
K <= 5
N <= 10 ^ 5
1 <= M <= 2 *(10 ^ 5)
出力
1本のライン、即ち、最小長、及び
サンプル入力
4 3 6
1 3 4
1 2 4
1 3 9
1 4 6
2 3 2
2 5
3 4 8
1 3 4
1 2 4
1 3 9
1 4 6
2 3 2
2 5
3 4 8
サンプル出力
11
シュタイナーの木、この問題カードspfa、私は行くを持っていました。。。
1つの#include <ビット/ STDC ++ H> 2 使用して 名前空間STDを、 3 の#defineっ長い長い 4 int型 CONST N = 1E5 + 10 。 5 int型 CONST M = 100 。 6 LLの CONST INF = 1E15。 7 構造体の縁{ 8 INT に、NT、W。 9 } E [N << 2 ]。 10 構造体ノード{ 11 のLL D。 12 int型のX; 13 ノード(LL _D、INT_x){ 14 D = _d。X = _x。 15 } 16 ブール 演算子 <(constのノード&RHS)のconst { 17 リターン D> rhs.d。 18 } 19 }。 20 int型 CNT、H [N]、N、P、M、VIS [N]、[ 10 ]、ID [N]。 21 LLのF [N] [M]、D [N]。 22キュー<ノード> Q。 23インラインint型リード(){ 24 、INT X = 0。チャー C = 0 。 25 しばらく(!isdigit(c)参照)、C = getchar関数(); 26 一方(isdigit(c)参照)、X = X * 10 +(C ^ 48)、C = GETCHAR()。 27 リターンX; 28 } 29 ボイドは(追加のint、int型 B、INT C){ 30 E [++ CNT] .TO = Bと、 31 E [CNT] .W = C。 32 E [CNT] .nt =さH [A]。 33 H [A] = CNT。 34 } 35 ボイドダイクストラ(){ 36 のmemset(VIS、0、はsizeof(VIS))。 37 ながら(!q.empty()){ 38 INT X。 39 ながら(!q.empty()){ 40 、X = q.front()X。 41 q.pop()。 42 もし(!VIS [X])ブレーク。 43 } 44は、 [X] = VIS 1 。 45 のために(int型 [X] I = hを、I; I = E [I] .nt){ 46 のint V = E [I] .TO。 47 であれば(D [V]> D [X] + eは[i]は.W){ 48 D [V]、D [X] + = E [I] .Wと、 49 q.push(ノード(D [V]、V))。 50 } 51 } 52 } 53 } 54 INT メイン(){ 55 // のscanf( "%D%D%D"、&N、&P、&M)。 56 N = )(読み取ります。 57 、P = )(読み取ります。 58 、M = )(読み取ります。 59 のためには、(int型 I = 1 ; I <= P、iは++ ){ 60 [I] = 読み取ります(); 61 ID [[I] = I。 62 } 63 ながら(M-- ){ 64 INT X、Y、Z。 65 X =リード()。Y =読み取り(); Z = リード()。 66 // のscanf( "%D%D%D"、およびX&Y、およびZ)。 67 追加(X、Y、Z)。 68 追加(X、Y、Z)。 69 } 70 のための(int型 i = 1 ; iがn = <I ++ ) 71 のための(INT J = 0 ; J <(1つの)<< P; J ++ ) 72の F [I] [J] = INF。 73 のために(int型 I = 1 ; I <= P iが++ ) 74 F [[I]] [1 << ID [[I]] - 1 ] = 0 ; 75 のための(int型のk = 1 ; <(k 1 k個++; << P){) 76 のための(int型 I = 1 [I] = D iが++; iが<= N)INF。 77 のためには、(int型 i = 1 ; iがn = <; iは++ ){ 78 のために(INT X = K・(K- 1); X、X =(X- 1)・K){ 79 のLL TMP = F [i]が[X] + F [i]が[K- X]。 80 F [i]が[K] = 分(F [i]が[K]、TMP)。 81 } 82 であれば(F [i]が[K] < INF){ 83 q.push(ノード(F [i]が[K]、I))。 84 D [I] = F [i]が[K]。 85 } 86 } 87 ダイクストラ()。 88 のためには、(int型 i = 1 ; iがn = <; iは++)F [i]が[K] = D [i]は、 89 } 90 のprintf(" %LLDする\ n " [F、1 ]] [(1 << P) - 1 ])。 91 リターン 0 ; 92 }