[テンプレート]倍小さいスパニングツリー

1  / * (最小スパニングツリートラバーサル図の全ての側面に属していない)のために
 2      回路添加しながら発生する電流の最小スパニングツリー
 3      除去するために、現在のエッジ重み他方側の最大値よりもループを
 4      現在のツリーを、総録音重量
 5  選択ツリーサイクル上記総重量が最小を生成する、第二の最小スパニングツリーれる* / 
6  / * 上記の練習は一度だけ、最小スパニングツリーを横断していますが、最小スパニングツリーに列挙側を削除した場合、望ましくないように、それは、N-2回の最小スパニングツリーを必要とする* / 
7の#include <cstdioを>
 8。の#include <CStringの>
 9。の#include <アルゴリズム>
 10の#include <キュー>
 11。 使用した 名前空間STD;
 12であるのtypedef対< INTINT > 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(01 ));
 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 }

 

おすすめ

転載: www.cnblogs.com/xiaobuxie/p/11391892.html