Fişierul intrare/ieşire:bellmanford.in, bellmanford.outSursăArhiva Educationala
AutorArhiva EducationalaAdăugată deGavrilaVladGavrila Vlad GavrilaVlad
Timp execuţie pe test0.5 secLimită de memorie20480 kbytes
Scorul tăuN/ADificultateN/A

Vezi solutiile trimise | Statistici

Algoritmul Bellman-Ford

Se dă un graf orientat conex cu N noduri şi M muchii cu costuri. Definim un lanţ ca fiind un şir de noduri cu proprietatea că între oricare două consecutive există o muchie. Costul unui lanţ este dat de suma costurilor muchiilor care unesc nodurile ce îl formează. Definim un ciclu ca fiind un lanţ cu proprietatea că primul element al său este egal cu ultimul.

Cerinţă

Să se determine dacă în graful dat există un ciclu de cost negativ. Dacă nu există, să se determine costul minim al unui lanţ de la nodul 1 la fiecare dintre nodurile 2, 3, ... , N-1, N.

Date de intrare

Fişierul de intrare bellmanford.in conţine pe prima linie numerele N şi M cu semnificaţia din enunţ. Pe următoarele M linii se vor afla câte 3 numere x, y şi c cu semnificaţia că există o muchie de cost c de la nodul x la nodul y.

Date de ieşire

În fişierul de ieşire bellmanford.out se va afişa pe prima linie mesajul "Ciclu negativ!" dacă în graf există un astfel de ciclu sau, în caz contrar, N-1 numere separate printr-un spaţiu. Al i-lea număr va reprezenta costul minim al unui lanţ de la nodul 1 la nodul i+1.

Restricţii

  • 1 ≤ N ≤ 50 000.
  • 1 ≤ M ≤ 250 000.
  • Costurile muchiilor sunt numere întregi cel mult egale în modul cu 1 000.

Exemplu

bellmanford.inbellmanford.out
5 8
1 3 -3
1 5 7
3 2 -2
3 4 7
5 1 4
5 2 3
5 3 4
4 5 3
-5 -3 4 7

Soluţie

Drumul de cost minim într-un graf de la o sursă la celelalte noduri se poate determina în complexitate O(M*log2N) folosind algoritmul lui Dijkstra. Totuşi, acest algoritm necesită costuri pozitive pe muchii, deci nu va ajuta la rezolvarea acestei probleme. În acest caz, se foloseşte algoritmul Bellman-Ford. Spre deosebire de algoritmul Dijkstra, care foloseşte muchiile o singură dată pentru îmbunătăţirea costului, Bellman-Ford foloseşte fiecare muchie de N-1 ori, repetarea asigurând propagarea distanţei minime prin graf. Algoritmul permite detectarea ciclurilor de cost negativ, apărând în cazul în care, după cele N-1 repetiţii, există o muchie care îmbunătăţeşte costul vreunui nod. O demonstraţie a algoritmului există pe Wikipedia.

Etape de rezolvare

O soluţie brute-force de complexitate O(N*M) obţine 35 puncte. Se deduce imediat o îmbunătăţire a algoritmului: în cazul în care costul unui nod nu a fost îmbunătăţit, folosirea muchiilor care pornesc din el este inutilă. Astfel, se poate ţine o listă de noduri, la fiecare pas scoţând un element din aceasta. Se va încerca îmbunătăţirea costului nodurilor vecine, introducându-le în listă în cazul scăderii costului, dacă nu apar deja. Această listă se poate implementa printr-un heap, selectând la fiecare pas nodul de cost minim, soluţia obţinând 100 de puncte, sau printr-o coadă, soluţia obţinând, de asemenea, 100 de puncte. Deşi au complexităţi teoretice de O(N*M*log2N), respectiv O(N*M), cele două soluţii se comportă mult mai bine în practică.

Determinarea drumului de cost minim reprezintă o subproblemă des întâlnită, astfel că algoritmul Bellman-Ford poate fi folosit cu succes, având performanţe asemănătoare algoritmului lui Dijkstra.

Aplicaţii

Trebuie sa te autentifici pentru a trimite solutii. Click aici

Cum se trimit solutii?

remote content