件名の説明:
ある n
村の家は。私たちは井戸を構築し、パイプを敷設して、すべての住宅のために水を供給します。
各家のために i
、私たちは、直接コストとその中にうまく構築することができますどちらか wells[i]
だけでなく、それまで他からの水で、またはパイプ。家との間のパイプを敷設するためのコストはアレイによって与えられ pipes
、それぞれが、 pipes[i] = [house1, house2, cost]
接続するコストを表し house1
と house2
一緒にパイプを使用します。接続は双方向です。
すべての家に水を供給するために最低限の総コストを検索します。
例1:
入力:N = 3、ウェル= [1,2,2]、パイプ= [1,2,1]、[2,3,1] 出力:3 説明: 画像はパイプを使用して接続住宅のコストを示します。 最善の戦略は、トータルのコストは3であるコスト1との最初の家でよくを構築し、コスト2でそれに他の家を接続することです。
制約:
1 <= n <= 10000
wells.length == n
0 <= wells[i] <= 10^5
1 <= pipes.length <= 10000
1 <= pipes[i][0], pipes[i][1] <= n
0 <= pipes[i][2] <= 10^5
pipes[i][0] != pipes[i][1]
ソリューション:
図1に示すように、アレイのウェルコストは、インデックス0に村との間の接続から見ることができます
村通路を通って村の0でのみ水村(〜nは番号1)2は、 - すなわち、ちょうどすべての村と通信する必要がある、すなわち、最小スパニングツリーを形成し、クラスカルのアルゴリズムを使用することができる:すなわち、 :
(大、小)右側の順に応じた重みは、スパニングツリーが付加されているが、スパニングツリーに追加するときのエッジに参加しないであろうエッジを有する環を形成します。ツリーに含まれるまで、{\ displaystyleのV-1} アップエッジ。これらのエッジは、図2の最小スパニングツリーで構成されています。
アルゴリズムの時間計算量はクラスカルある{\ DisplayStyle E \ログE} 。
図3は、二つの村互いに素なセットを接続することができるか否かが判断されます。Lee215実装次のように:
int型[] UFを。 公共 INT minCostToSupplyWater(整数 nは、値int []のウェルを、int型[] []パイプ){ UF = 新しい INT [N + 1 ]。 リスト < INT []>エッジ= 新規のArrayList <> (); 以下のために(int型 i = 0; iがn <; iは++ ){ UF [I + 1] = I + 1 。 edges.add(新しい INT [] {0、I + 1 、ウェル[I]})。 } のための(INT [] P:パイプ){ edges.add(P)。 } Collections.sort(縁部、(B) - > Integer.compare([2]、B [2 ]))。 int型のres = 0 ; 用(INT [] E:エッジ){ int型のx =検索(E [0])、Y =見つける(E [1 ])。 もし(!X = Y){ RES + = E [2 ]。 UF [X] = Y。 - N。 } } 戻りRES。 } プライベート int型の検索(INT X){ もし(!X = UF [X])UF [X] = (UFは、[X])を見つけます。 戻りUFを[X]。 }
この実装は非常に簡単です。
私は、テンプレートの彼らの共通クラスWQUPCセット(パスcomparessと加重迅速な労働組合)を達成するために適用される、それは少し冗長に見えますが、パフォーマンスを向上させることができます。
クラスソリューション{ クラスWQUPCは{ int型[]のIDを、 int型[] SZを。 WQUPC(int型N){ ID = 新しい INT [N]。 SZ = 新しい INT [N]。 以下のために(int型 i = 0; iがn <; iは++ ){ ID [I] = I。 SZ [I] = 1 。 } } int型のルート(int型I){ 一方(ID [I]!= I){ ID [i]は = ID [ID [I]]。 I = ID [i]は、 } 戻りID [i]は、 } ブール接続(int型 I、int型のJ){ 戻りルート(I)== ルート(J)。 } ブール連合(int型私は、INT {j)は int型 PI = ルート(I)。 int型 PJ = ルート(J)。 もし(piは== PJ)を返す 偽。 もし(SZ、π>SZ [PJ]){ ID [PJ] = ID [PI]。 SZ [PI] + = SZ [PJ]。 } 他{ ID [PI] = ID [PJ]。 SZ [PJ] + = SZ [PI]。 } を返す 真。 } } 公共 のint minCostToSupplyWater(整数 nは、値int []のウェルを、int型[] []パイプ){ リスト < INT []>エッジ= 新規のArrayListを<> (); 以下のための(int型私= 0; I <wells.length。I ++ ){ edges.add(新しい INT [] {0、I + 1 、ウェル[I]})。 } のための(int型[]パイプ:パイプ){ edges.add(新しい INT [] {パイプ[0]、パイプ[1]、管[2 ]})。 } Collections.sort(縁部、(B) - > Integer.compare([2]、B [2 ]))。 WQUPCのQU = 新しい WQUPC(N + 1 )。 int型のres = 0 ; 以下のために(int型[]エッジ:エッジ){ 場合(qu.union(エッジ[0]、エッジ[1 ])){ // するSystem.out.println(エッジ[0] + "" +エッジ[1] + "" +エッジ[2])。 RES + =エッジ[2 ]。 } } 戻りRES。 } }