1955 - plimbare1
Cerința[edit | edit source]
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[edit | edit source]
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[edit | edit source]
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[edit | edit source]
• 1 ≤ N ≤ 100.000
• 1 ≤ M ≤ 120.000
• 1 ≤ c ≤ 250
– număr natural
• drumurile sunt bidirecționale
Exemplu:[edit | edit source]
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[edit | edit source]
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.
Rezolvare[edit | edit source]
<syntaxhighlight lang="python3"> Inf = float('inf')
def init(n):
return list(range(n + 1))
def find(x, T):
if x != T[x]: T[x] = find(T[x], T) return T[x]
def union(a, b, T):
T[find(a, T)] = find(b, T)
def kruskal(G, n):
rez = 0 T = init(n) afis = [] for x, y, z in G: r1 = find(x, T) r2 = find(y, T) if r1 != r2: rez += z afis.append((x, y)) union(r1, r2, T) return rez
if __name__ == "__main__":
with open("plimbare1.in", 'r') as fin, open("plimbare1.out", 'w') as fout: n, m = map(int, fin.readline().split()) G = [] for _ in range(m): line = list(map(int, fin.readline().split())) op = line[0] if op == 1: x, y = line[1:3] G.append((x, y, 0)) else: x, y, w = line[1:4] G.append((x, y, w)) G.sort(key=lambda x: x[2]) rez = kruskal(G, n) fout.write(str(rez) + '\n')
</syntaxhighlight>