Cod sursa(job #3212478)

Utilizator prares06Papacioc Rares-Ioan prares06 Data 11 martie 2024 19:41:45
Problema Algoritmul Bellman-Ford Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.69 kb
#include<fstream>
#include<vector>
#include<queue>
#define pii std::pair<int, int>

std::ifstream fin("bellmanford.in");
std::ofstream fout("bellmanford.out");

int n, m;
bool has_negative_cycle; //o folosim ca sa stim cand oprim programul, pentru a evita un ciclu infinit
std::vector<std::vector<pii> > G; //se face un artificiu pentru a stoca pentru fiecare vecin si costul asociat muchiei

void BellmanFord(int start) {
	std::vector<int> D(n + 1, 0x3f3f3f3f); //0x3f3f3f3f este un miliard si ceva, suficient ca inmultit cu 2 sa nu dea overflow la tipul de date int
	std::queue<pii> Q;
	std::vector<bool> viz(n + 1, false); //noteaza daca elementul e in coada la un moment dat
	std::vector<int> iq(n + 1, 0); //noteaza de cate ori intra elementul in coada

	D[start] = 0; //logic ca distanta de la un nod la el insusi e 0
	viz[start] = 1;
	++iq[start];
	Q.push({ start, 0 });

	while (!Q.empty()) {
		pii curr = Q.front();
		viz[curr.first] = 0;
		Q.pop();

		for (const pii& vecin : G[curr.first])
			if (D[vecin.first] > D[curr.first] + vecin.second) {
				D[vecin.first] = D[curr.first] + vecin.second;
				if (!viz[vecin.first]) {
					viz[vecin.first] = true;
					Q.push({ vecin.first, D[vecin.first] });
					if (++iq[vecin.first] > n) {
						has_negative_cycle = true;
						return; //programul se opreste, am gasit ciclu negativ
					}
				}
			}
	}

	for (int i = 2; i <= n; ++i)
		if (D[i] == 0x3f3f3f3f)
			fout << -1 << ' ';
		else
			fout << D[i] << ' ';
}

int main() {
	fin >> n >> m;

	int x, y, c;

	G.resize(n + 1);

	for (; fin >> x >> y >> c;)
		G[x].push_back({ y, c });

	BellmanFord(1);

	if (has_negative_cycle)
		fout << "Ciclu negativ!";
}