Cerința
Personajul acestei probleme este Lucian. Lucian locuiește în tara lui Verde Împărat, această tară având n
orașe, numerotate de la 1
la n
. Cum în orice poveste cu împărați există și o prințesă, și în problema noastră avem o prințesă, să o numim Maria. Maria este fiica lui Verde Împărat și în același timp prietena lui Lucian.
În tara lui Verde Împărat se apropie sărbătorile, iar ca să fie sigur de un nou mandat, împăratul a promis că va repara câteva drumuri, astfel încât să se poată ajunge din orice oraș, în oricare alt oraș, mergând doar pe drumuri care nu sunt stricate. Fiecare drum care este stricat are un cost de reparație , și având în vedere că se apropie sărbătorile, Împăratul ar vrea să repare drumurile optim, astfel încât să obțină un cost cât mai mic. Știind că Lucian vrea să-i ceară mâna Mariei, Împăratul i-a încredințat lui Lucian această sarcină, iar în cazul în care nu va putea să o îndeplinească îl va izgoni din tară. Lucian nu a fost prezent mai deloc la orele de algoritmică din liceu și vă cere vouă ajutorul pentru această problema complicată. Având la dispoziție lista drumurilor, precum și lista drumurilor stricate, voi trebuie să-i spuneți lui Lucian care este suma minimă pe care trebuie să o folosească pentru a se putea ajunge din orice oraș în oricare alt oraș.
Date de intrare
Fișierul plimbare1.in
conține pe prima linie două numere N
și M
, reprezentând numărul de orașe și numărul de drumuri din tara lui Verde Împărat. Pe următoarele M
linii vor fi descrise drumurile sub următoarea formă:
1 a b
– există un drum întrea
șib
;2 a b c
– există un drum întrea
șib
care poate fi reparat cu costulc
.
Date de ieșire
Fișierul plimbare1.out
conține pe prima linie un număr S
, reprezentând costul minim al reparării drumurilor, pentru a se putea ajunge din orice oraș în oricare alt oraș.
Restricții și precizări
• 1 ≤ N ≤ 100.000
Exemplu
plimbare1.in
5 5 1 1 2 1 3 4 2 2 3 6 2 3 5 9 2 4 5 6
plimbare1.out
12
Explicație
Observăm că nu putem ajunge în orașul 3
din orașul 1
, sau din orașul 2
în orașul 3
, de aceea trebuie să reparăm un drum, astfel încât să fie posibil să ajungem în orașul 3
. Astfel, selectam drumul 2 3
cu costul 6
. După ce am reparat acest drum observăm că nu putem ajunge în orașul 5
. Avem două drumuri posibile de reparat pentru a ajunge apoi în orașul 5
, 3 5
cu costul 9
si 4 5
cu costul 6
. Îl vom alege pe cel mai mic (cel cu costul 6
), astfel după ce reparăm și acest drum putem ajunge din orice oraș în oricare altul.
#include <bits/stdc++.h> using namespace std; ifstream cin("plimbare1.in"); ofstream cout("plimbare1.out"); int n , m , a , b , c , cer ; long long t; struct poz { int i , j , c; }V[125001]; int T[100001]; int comp(poz a , poz b) { return a.c < b.c; } int leaga(int r1 , int r2) { T[r2] = T[r1]; } int radacina(int a) { if(a == T[a]) return a; else return T[a] = radacina(T[a]); } void kruskal() { int r1 , r2 , k = 0; for(int i = 1 ; i <= m ; i++) { r1 = radacina(V[i].i); r2 = radacina(V[i].j); if(r1 != r2) { t += V[i].c; leaga(r1 , r2); } } } int main() { cin >> n >> m; for(int i = 1 ; i <= m ; i++) T[i] = i; for(int i = 1 ; i <= m ; i++) { cin >> cer; if(cer == 1) { cin >> a >> b; V[i].i = a; V[i].j = b; V[i].c = 0; } else { cin >> a >> b >> c; V[i].i = a; V[i].j = b; V[i].c = c; } } sort(V + 1 , V + m + 1 , comp); kruskal(); cout << t; return 0; }