1 / * (最小スパニングツリートラバーサル図の全ての側面に属していない)のために 2 回路添加しながら発生する電流の最小スパニングツリー 3 除去するために、現在のエッジ重み他方側の最大値よりもループを 4 現在のツリーを、総録音重量 5 選択ツリーサイクル上記総重量が最小を生成する、第二の最小スパニングツリーれる* / 6 / * 上記の練習は一度だけ、最小スパニングツリーを横断していますが、最小スパニングツリーに列挙側を削除した場合、望ましくないように、それは、N-2回の最小スパニングツリーを必要とする* / 7の#include <cstdioを> 8。の#include <CStringの> 9。の#include <アルゴリズム> 10の#include <キュー> 11。 使用した 名前空間STD; 12であるのtypedef対< INT、INT > PII; 13である CONST INT MAXN = 111; 14 CONST INT INF = 0x3f3f3f3f ; 15 INT G [MAXN] [MAXN]; // 隣接行列図メモリ 16 INTマックス[MAXN] [MAXN]; //は、iがjに最小全域木重み最大エッジを表している 17。 BOOL [MAXN] [MAXN]使用; //は、最小スパニングツリーの側面に参加するかどうかを決定する 18ことである INT [MAXN】プリ; // 最小スパニングツリーの点前駆体 19。 INT DIS [MAXN]; //はポイントが保存フォーカス、各点の最短辺 20がある BOOL ; VIS [MAXN] // 点が最小スパニングツリーに追加されたか否かを判断 21である INT T、N-、M; 22は 、INT (プリム) 23です { 24 INTの和= 0 。 25 のmemset(VIS、偽、はsizeof (VIS)); 26 のmemset(使用、偽、はsizeof (使用されます))。 27 のmemset(最大、0、はsizeof (最大))。 28 のmemset(DIS、0x3f3f3f3f、はsizeof (DIS))。 29の DIS [ 1 ] = 0 。 30 予備[ 1 ] = 0 。 31 PRIORITY_QUEUE <PII、ベクトル<PII>、大きな<PII>> Q。 32 q.push(make_pair(0、1 )); 33である INTすべて= 0 ; 34である 一方で(!{q.empty()) 35 INT U = q.top()SECOND ;. 36 q.pop(); 37 [ IF(VIS [U])続行; 38である VIS [U] = 1 ; 39 //はI Uが最小スパニングツリー、およびわずかDISに従って変更プリ間I MAXを変更するために使用される配列を入力する場合にのみ決定されます; 40 [U]中古[プレ[U] =中古[プレ[U] [U] = 1 ; 41で ++ すべて、 42はある SUM = + DIS [U]; 43れます 用(INT J = 1。 ; J <= N-; ++ J){ 44は、 IF (VIS [J]){ 45 IF(!J = U)最大[J] [U] =最大[U] [J] = ;(MAX [J] [事前[U]、DIS [U])maxは 46である 他の最大[J] [U] = 0 ; 47 //がDPに対応し、jが最長辺Uとの間で決定されます辺の重み 48 } 49 他 IF(G [J] [U] =!0x3f3f3f3f && DIS [J]> G [J] [U]){ 50 DIS [J] = G [J] [U]; 51は、 予め[ J] = U; 52であり ; q.push(make_pair(DIS [J]、J)) 53であります } 54である } 55 } であり、56 IF(全て<N-)リターン - 1。; 57は、 リターン SUM; // 重量値と最小スパニングツリー 58 } 59 INT SMST(INT SUM)// SUMは、体重値と最小スパニングツリーであります 60 { 61は、 INT ANS = 0x3f3f3f3f ; 62である ため(INT I = 1 ; I <= N; I ++)// エッジを越え列挙最小スパニングツリー 63である ため(int型 Jは=私は+ 1、J <= N; J ++) 64 IF(G [I] [J]!= 0x3f3f3f3f &&!中古[I] [J]) 65 // 添加した後、接続i及びj(保証構成スパニング)としない最小スパニングツリーの側面において、そして、最大の削除I jの右側には、縁 66の ANS =分(ANSを、SUM + G [I] [J] - マックス[I] [J]); 67 IF(ANS == 0x3f3f3f3f)リターン - 1。 。 68 リターンANS; 69 } 70 のint main()の 71は 、{ 72 scanfの(" %のD "、&T)、 73は 、一方(T-- ) 74 { 75 のscanf(" %D%dの"、&N、&M)。 76 のmemset(G、0x3f3f3f3f、はsizeof (G))。 77 のために(int型 i = 1 ; iが<= N; I ++)G [i]は[I] = 0 ; 78 INTのU、V、W。 79 のために(int型 I = 1 ; I <= M; ++ i)が{ 80 のscanf(" %D%D%D "、&U&V、およびW) 81 G [U] [V] = G [V] [U] = 分(G [U] [V]、W)。 82 } 83 int型 ANS = プリム(); 84 IF(ANS == - 。1)プット(" 未ユニークなの!" ); 85 他の IF(SMST(ANS)== ANS)プット(" 未ユニークなの!" ); 86 他のprintf(" %Dの\のN- " 、ANS); 87 // タイトルを決定することにするかどうかを一意最小スパニングツリー 88 } 89 リターン 0 ; 90 }