Cod sursa(job #3284217)

Utilizator Dulea_AndreiDulea Andrei-Lucian Dulea_Andrei Data 11 martie 2025 11:39:23
Problema Algoritmul Bellman-Ford Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.23 kb
#include <bits/stdc++.h>
using namespace std;

const int INF = 1e9;

// Funcția SPFA (o variantă optimizată a Bellman-Ford)
// Calculează distanțele minime de la nodul 'start' către toate celelalte noduri
// folosind o coadă pentru a procesa doar nodurile actualizate.
// Returnează true dacă nu există cicluri negative, altfel false.
bool spfa(int start, int n, vector<vector<pair<int, int>>>& adj, vector<int>& dist) {
    dist.assign(n + 1, INF);
    vector<int> count(n + 1, 0);    // numărul de relaxări pentru fiecare nod
    vector<bool> inQueue(n + 1, false); // indică dacă nodul se află în coadă

    queue<int> q;
    dist[start] = 0;
    q.push(start);
    inQueue[start] = true;

    while (!q.empty()) {
        int u = q.front();
        q.pop();
        inQueue[u] = false;

        // Relaxăm toate muchiile care ies din nodul curent
        for (auto &edge : adj[u]) {
            int v = edge.first;
            int w = edge.second;
            if (dist[u] + w < dist[v]) {
                dist[v] = dist[u] + w;
                // Dacă nodul v nu se află deja în coadă, îl adăugăm
                if (!inQueue[v]) {
                    q.push(v);
                    inQueue[v] = true;
                    count[v]++;
                    // Dacă un nod este relaxat de cel puțin n ori,
                    // atunci există un ciclu de cost negativ.
                    if (count[v] >= n)
                        return false;
                }
            }
        }
    }
    return true;
}

int main() {
    ifstream fin("bellmanford.in");
    ofstream fout("bellmanford.out");

    int n, m;
    fin >> n >> m;
    // Construim lista de adiacență pentru graf
    vector<vector<pair<int, int>>> adj(n + 1);
    for (int i = 0; i < m; i++) {
        int u, v, cost;
        fin >> u >> v >> cost;
        adj[u].push_back({v, cost});
    }

    vector<int> dist;
    // Pornim de la nodul 1
    if (!spfa(1, n, adj, dist)) {
        fout << "Ciclu negativ!";
        return 0;
    }

    // Afișăm costul minim pentru nodurile 2, 3, ..., N
    for (int i = 2; i <= n; i++) {
        fout << (dist[i] == INF ? -1 : dist[i]) << " ";
    }
    return 0;
}