Cod sursa(job #3341215)

Utilizator mircea_007Mircea Rebengiuc mircea_007 Data 18 februarie 2026 15:29:31
Problema Flux Scor 100
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.25 kb
// phi(src) = 0, phi(dest) = 0, bagi gaus si gata

#include <fstream>
#include <iostream>
#include <iomanip>
#include <cassert>

#include <algorithm>
#include <vector>

#include <tuple>
#include <valarray>

template<class T> using vec = std::vector<T>;
using ftype = long double;

constexpr int NIL = -1;

constexpr ftype EPS = 1e-10;
int sgn( ftype x ) { return (x > -EPS) - (x < +EPS); }

vec<ftype> solve_lin( vec<std::valarray<ftype>> mat ) {
  int m = (int)mat.size();
  int n = (int)mat.front().size() - 1;

  vec<int> eq_id;
  int _eq_id = 0;
  for( int t = 0; t < n; t++ ){
    int eq = NIL;
    for( int i = _eq_id; i < m; i++ )
      if( sgn( mat[i][t] ) )
        eq = i;

    if( eq == NIL ) { eq_id.push_back( NIL ); continue; } // pica daca graful nu e conex

    std::swap( mat[eq], mat[_eq_id] );
    eq = _eq_id++;
    mat[eq] *= 1 / mat[eq][t];

    eq_id.push_back( eq );
    for( int i = 0; i < m; i++ )
      if( i != eq )
        mat[i] -= mat[eq] * mat[i][t];
  }

  vec<ftype> ret(n, 0); // ups :)
  for( int i = 0; i < n; i++ )
    if( eq_id[i] != NIL )
      ret[i] = mat[eq_id[i]][n];

  return ret;
}

int main() {
  std::ifstream fin("flux.in");
  std::ofstream fout("flux.out");

  std::cerr << std::fixed << std::setprecision(3);
  fout << std::fixed << std::setprecision(10);

  int n, m;
  fin >> n >> m;

  int src = 0, dest = n - 1;

  vec<std::valarray<ftype>> mat(n, std::valarray<ftype>((ftype)0, n + 1));
  
  vec<std::tuple<int, int, int>> res;
  for( int i = 0; i < m; i++ ){
    int a, b, c;
    fin >> a >> b >> c;
    a--; b--;

    res.emplace_back( a, b, c );

    mat[a][a]++;
    mat[a][b]--;

    mat[b][b]++;
    mat[b][a]--;
  }

  {
    mat[src] = mat[dest] = std::valarray<ftype>((ftype)0, n + 1);
    mat[src][src] = 1;
    mat[src][n] = 0;

    mat[dest][dest] = 1;
    mat[dest][n] = 1;
  }

  vec<ftype> phi = solve_lin( mat );

  ftype max_mult = 1e18;
  for( const auto &[a, b, c]: res ){
    ftype delta = std::abs( phi[a] - phi[b] );
    if( !sgn( delta ) ) continue;
    max_mult = std::min( max_mult, c / delta );
  }

  for( ftype &x : phi ) x *= max_mult;

  ftype ret = 0;
  for( auto &[a, b, c]: res ){
    if( a == src ) ret += phi[b] - phi[a];
    if( b == src ) ret += phi[a] - phi[b];
  }

  fout << ret << std::endl;
  return 0;
}