Cod sursa(job #3356176)

Utilizator Cezar2009Cezar Mihai Titihazan Cezar2009 Data 29 mai 2026 23:59:22
Problema Flux Scor 96
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 4.15 kb
	// https://infoarena.ro/problema/flux

	//#ifdef _MSC_VER
	//	#define _CRT_SECURE_NO_WARNINGS
	//#elif  __GNUC__
	//	#pragma GCC optimize("Ofast,unroll-loops,inline")
	//	#pragma GCC target("avx2,bmi,bmi2,lzcnt,popcnt")
	//#endif

	//#define _USE_MATH_DEFINES

	#include <iostream>
	#include <fstream>
	#include <utility>
	#include <cstdint>
	//#include <cstdio>
	//#include <algorithm>
	#include <vector>
	//#include <array>
	//#include <list>
	//#include <forward_list>
	//#include <string>
	//#include <cstring>
	//#include <cmath>
	//#include <bitset>
	//#include <queue>
	//#include <stack>
	//#include <map>
	//#include <set>
	//#include <unordered_map>
	//#include <unordered_set>
	//#include <limits>
	//#include <climits>
	#include <iomanip>
	//#include <tuple>
	//#include <numeric>
	//#include <chrono>
	//#include <memory>

	using namespace std;

	using int64 = int64_t;
	using uint64 = uint64_t;
	using int32 = int32_t;
	using uint32 = uint32_t;
	using int16 = int16_t;
	using uint16 = uint16_t;
	using pii = pair<int, int>;
	using pll = pair<int64, int64>;

	#define all(x) (x).begin(), (x).end()
	#define allg(x) (x).begin(), (x).end(), greater<int>()
	#define sz(x) (int)(x).size()
	#define pb push_back
	#define eb emplace_back
	#define rfor(i, st, dr) for(auto i=(st); i<=(dr); ++i)
	#define for0(i,n) for(auto i=0; i<(n); ++i)
	#define rfor0(i,n) for(auto i=(n)-1; i>=0; --i)
	#define for1(i,n) for(auto i=1; i<=(n); ++i)
	#define rfor1(i,n) for(auto i=(n); i>=1; --i)
	#define foreach(x,a) for(auto& x : a)
	#define cforeach(x,a) for(const auto& x : a)
	#define ft first
	#define sd second
	#define cendl cout << "\n"
	#define fendl fout << "\n"
	#define FASTIO ios::sync_with_stdio(false); cin.tie(nullptr);

	//#define int int64

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

	//FILE* fin = fopen("", "r");
	//FILE* fout = fopen("", "w");

	const int NRMAX = 100;
	const double EPS = 1e-9;
	const double ZERO = 0.000;

	double mat[NRMAX + 5][NRMAX + 5];
	double dist[NRMAX + 5];
	bool viz[NRMAX + 5];
	vector<pii> gr[NRMAX + 5];

	void dfs(int x) {
		viz[x] = true;
		cforeach (it, gr[x]) {
			if (!viz[it.ft])
				dfs(it.ft);
		}
	}

	int32 main()
	{
		//FASTIO;

		int n, m, a, b, c;

		fin >> n;
		fin >> m;
		for1(i, m) {
			fin >> a >> b >> c;

			gr[a].eb(b, c); 
			gr[b].eb(a, c);
		}

		// verific sa fie drum pana la final
		dfs(1);
		if(!viz[n]) {
			fout << "0.000\n";
			return 0;
		}

		// initializam matricea de ecuatie
		mat[1][1] = 1.0;
		mat[1][n + 1] = 0.0; 
		for(int i = 2; i < n; ++i) {
			mat[i][i] = sz(gr[i]);

			cforeach(it, gr[i])
				mat[i][it.ft] -= 1.0;

			mat[i][n + 1] = 0.0; // rezultatul da 0
		}
		mat[n][n] = 1.0;
		mat[n][n + 1] = 1.0;

		// eliminarea gaussiana 
		for (int r = 1; r <= n; ++r) {	
			if (!(abs(mat[r][r]) <= EPS)) { // daca e aprox 0
				// daca elementul de pe [r][r] e 0 atunci cautam un element nou
				// desi nu ar trebui sa se intample asta la problema asta cred ... 

				// int i;

				// for (i = r + 1; i <= n; ++i)
				// 	if (!(abs(mat[i][r]) <= EPS))
				// 		break;

				// if (i > n) {
				// 	continue;
				// }

				// swap(mat[r], mat[i]);

				for (int i = 1; i <= n; ++i) { //  iau fiecare linie
					if (i == r)
						continue;

					double rp = mat[i][r] / mat[r][r];

					for (int j = 1; j <= n + 1; ++j) // toate din inainte is deja 0
						mat[i][j] -= rp * mat[r][j];
				}
			}
		}

		// aflam distantele in funcie de rezultatele aflate (mat[r][r] * dist_r = mat[r][n + 1])
		for (int r = 1; r <= n; ++r) { 
			dist[r] = mat[r][n + 1] / mat[r][r];
		}


		double rez = 0.0, k = 0.0;

		// aflam coeficientul cu care scalam
		for1(i, n) {
			cforeach(it, gr[i]) {
				if (it.sd > 0) {
					double flux = dist[it.ft] - dist[i];
					k = max(k, flux / it.sd);
				}
			}
		}

		if(k > EPS) { // daca exista un numar ca asta
			cforeach(it, gr[n]) {
				double flux = dist[n] - dist[it.ft];
				rez += flux / k;
			}
		}

		fout << setprecision(3) << fixed << rez << "\n";

		return 0;
	}

	/*
	*	Deci ideia e ca am unr rezervor si o sursa. eu trebuie sa duc volumul maxim de apa.
	*   Cata apa intra intr-un nod si iese. 
	*	de semenea pt oricare 2 puncte i si j suma volumelor de apa de pe oricare drum de la i la j sa fie constanta
	*/