Cod sursa(job #3341205)

Utilizator mircea_007Mircea Rebengiuc mircea_007 Data 18 februarie 2026 13:51:18
Problema Flux Scor 76
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.07 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-8;
int sgn( int 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;

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

    assert( eq != NIL ); // pica daca graful nu e conex

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

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

  vec<ftype> ret(n);
  for( int i = 0; i < n; i++ )
    ret[i] = mat[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( !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;
}