C.噂
Vovaは、彼がコンピュータゲームをプレイすることはないことを自分自身を約束した...しかし、最近ファイヤーストーム-有名なゲーム開発会社-彼らの最新のゲーム、Farcraftの世界を発表し、それは本当に人気となりました。もちろん、Vovaはそれを弾き始めました。
今、彼はクエストを解決しようとします。タスクはOvercityという名前の和解に来て、その中に噂を広めることです。
VovaはOvercity中のn文字があることを知っています。一部の文字は、互いに友人であり、彼らは、彼らが得た情報を共有します。またVovaは、彼または彼女は噂を広める開始しますので、彼は各文字を買収できることを知っています。i番目の文字は、噂を広めると引き換えに、CI金を望んでいます。文字は噂を聞いたとき、彼はすべての彼の友人にそれを伝え、彼らがそうで(無料で)彼らの友人に噂を広め、そして開始します。
すべてのn文字が噂を知ったときにクエストを終了します。Vovaはクエストを終了するために費やす必要がある金の最低額とは何ですか?
あなたが問題を完全に理解していないと思われる場合の注意事項を見てみましょう。
入力
(105≤1≤N≤105、0≤m)の最初の行は、2つの整数が含まれ、nおよびm - Overcityの文字数や友人の対の数。
i番目の文字が噂を拡散開始するように求められた金の量 - 2行目は、n個の整数のCI(109≤0≤CI)を含みます。
次に、m個の行は、それぞれ文字Xi及びYiが友人(1つの≤XI、YIさ≤N、XI≠YI)であることを表す数字(XI、YI)の対を含む、従います。各ペアが最も一度に記載されていることを保証されています。
出力は
1つの番号を印刷する-金Vovaの最小量は、クエストを終了するために費やす必要があります。
入力
5 2 2 5 3 4 8 1 4 4 5
出力
10
考える:明らかに互いに素セットを。
ACコード:
#include <ビット/ STDC ++ H> 使用して名前空間STDを、 #define N 100009 の#define INT長い長い int型のコスト[N]。 INT F [N]。 INT GETF(INT V){ 場合(Vの==のF [V]){ リターン; F [V] } 他{ F [V] = GETF(F [V])。 戻り[V] F; } } ボイドマージ(INT U、INT V){ int型の T1 = GETF(U)。 INT T2 = GETF(V)。 もし(!T1 = T2){ F [T2] = T1。 } } メイン(){署名された INT N、M。 CIN >> N >> M。 int型 SB = 0 ; int型 ANS = 0 ; 以下のために(int型 i = 1 ; iが<= N; iが++ ){ scanf関数(" %のLLDを"、およびコスト[I])。 SB + = コスト[i]は、 F [I] = I。 } もし(M == 0 ){ COUT << SB <<endl; リターン 0 ; } のために(int型 i = 0 ; iがmを<; iは++ ){ int型X、Y。 scanf関数(" %のLLDの%のLLD "、およびX&Y)。 (x、y)をマージ。 } / * {ため(iは++; iがn = <I = 1 INT) IF(I == [I] F){ COUT << I <<」「。 } } COUT << ENDL。* / のために(int型 i = 1 ; iがn = <; iは++ ){ コスト[GETF(I)] =分(コスト[GETF(I)]、コスト[I])。//キー:先祖に割り当てられた最小コストの各セット。 //} ため( INT I = 1 ; I <= N; I ++は){ IF(I == F [I]){ ANS + =コスト[I]; } } のprintf(" %LLDの\のN- " 、ANS) ; 戻り 0 ; }