Cod sursa(job #3300831)

Utilizator MihaiZ777MihaiZ MihaiZ777 Data 19 iunie 2025 13:15:33
Problema Floyd-Warshall/Roy-Floyd Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.74 kb
#include <algorithm>
#include <cmath>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <fstream>
#include <cstring>
#include <vector>
using namespace std;

#define fast_io ios::sync_with_stdio(0); cin.tie(0); do{}while(0)
typedef long long ll;

const int MAXN = 105;
const int INF = 0x3f3f3f3f;

ifstream fin("royfloyd.in");
ofstream fout("royfloyd.out");

struct Edge {
	int dest, c;

	bool operator <(const Edge& other) const {
		return c > other.c;
	}
};

int n;
vector<Edge> graph[MAXN];

queue<int> q;
bool inQueue[MAXN];
int weights[MAXN];
int relaxations[MAXN];

priority_queue<Edge> h;
int distances[MAXN];
bool visited[MAXN];

int ans[MAXN][MAXN];

void ReadData() {
	fin >> n;
	int c;
	for (int i = 1; i <= n; i++) {
		for (int j = 1; j <= n; j++) {
			fin >> c;
			if ((c == 0 && i != j) || i == j) {
				continue;
			}
			graph[i].push_back({j, c});
		}
	}
}

bool BellmanFord(int start) {
	n++;
	memset(weights, INF, sizeof(weights));
	weights[start] = 0;
	inQueue[start] = true;
	q.push(start);

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

		for (Edge next : graph[curr]) {
			if (weights[next.dest] < weights[curr] + next.c) {
				continue;
			}

			weights[next.dest] = weights[curr] + next.c;
			if (!inQueue[next.dest]) {
				q.push(next.dest);
				inQueue[next.dest] = true;
				relaxations[next.dest]++;
			}
			if (relaxations[next.dest] > n) {
				return false;
			}
		}
	}
	n--;
	return true;
}

void AdaptCostsForDijkstra() {
	for (int i = 1; i <= n; i++) {
		graph[n + 1].push_back({i, 0});
	}

	if (!BellmanFord(n + 1)) {
		// err
	}

	for (int u = 1; u <= n; u++) {
		for (auto &e : graph[u]) {
			e.c = e.c + weights[u] - weights[e.dest]; 
		}
	}
}

void Dijkstra(int start) {
	memset(distances, INF, sizeof(distances));
	memset(visited, false, sizeof(visited));
	distances[start] = 0;
	h.push({start, 0});

	while (!h.empty()) {
		Edge curr = h.top();
		h.pop();

		if (visited[curr.dest]) {
			continue;
		}
		visited[curr.dest] = true;

		for (Edge next : graph[curr.dest]) {
			if (distances[next.dest] < distances[curr.dest] + next.c) {
				continue;
			}

			distances[next.dest] = distances[curr.dest] + next.c;
			h.push({next.dest, distances[next.dest]});
		}
	}
}

void Solve() {
	AdaptCostsForDijkstra();
	for (int i = 1; i <= n; i++) {
		Dijkstra(i);
		for (int j = 1; j <= n; j++) {
			ans[i][j] = (distances[j] >= INF) ? 0 : distances[j] - weights[i] + weights[j];
		}
	}

	for (int i = 1; i <= n; i++) {
		for (int j = 1; j <= n; j++) {
			fout << ans[i][j] << ' ';
		}
		fout << '\n';
	}
}

int main() {
		ReadData();
		Solve();
		return 0;
}