Cod sursa(job #2706206)

Utilizator retrogradLucian Bicsi retrograd Data 14 februarie 2021 11:36:41
Problema Flux Scor 100
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.3 kb
#include <bits/stdc++.h>

using namespace std;
using ld = long double;
using mat = vector<vector<ld>>;
const ld EPS = 1e-9;

pair<vector<int>, int> RowEchelon(mat& A) {
  int n = A.size(), m = A[0].size(), sgn = 1; 
  vector<int> piv;
  for (int i = 0, rnk = 0; i < m && rnk < n; ++i) {
    for (int j = rnk + 1; j < n; ++j) 
      if (abs(A[j][i]) > abs(A[rnk][i]))
        swap(A[j], A[rnk]), sgn = -sgn;
    if (abs(A[rnk][i]) < EPS) continue;
    for (int j = 0; j < n; ++j) {
      ld coef = A[j][i] / A[rnk][i];
      if (j == rnk || abs(coef) < EPS) continue;
      for (int k = 0; k < m; ++k)
        A[j][k] -= coef * A[rnk][k];
    }
    piv.push_back(i); ++rnk;
  }
  return {piv, sgn};
}
vector<ld> SolveLinear(mat& A) {
  int m = A[0].size() - 1;
  auto piv = RowEchelon(A).first;
  if (piv.size() > m) return {};
  vector<ld> sol(m, 0.);
  for (int i = 0; i < (int)piv.size(); ++i)
    sol[piv[i]] = A[i][m] / A[i][i];
  return sol;
}

struct DSU {
  vector<int> link;
  DSU(int n) : link(n) { iota(link.begin(), link.end(), 0); }
  void Unite(int a, int b) { 
    a = link[a]; b = link[b];
    for (auto& i : link) if (i == a) i = b; 
  }
  bool Same(int a, int b) { return link[a] == link[b]; }
};

int main() {
  ifstream cin("flux.in");
  ofstream cout("flux.out");
  
  int n, m; cin >> n >> m;
  vector<tuple<int, int, int>> cons;
  DSU D(n);
  for (int i = 0; i < m; ++i) {
    int a, b, c; cin >> a >> b >> c;
    cons.emplace_back(a - 1, b - 1, c);
    D.Unite(a - 1, b - 1);
  }

  if (!D.Same(0, n - 1)) {
    cout << 0 << endl;
    return 0;
  }

  mat A(n, vector<ld>(n + 1));
  A[0][0] = 1; A[n - 1][n] = 1;
  for (auto itr : cons) {
    int a, b, c; tie(a, b, c) = itr;
    if (a > 0) A[a][a] += 1, A[a][b] -= 1;
    if (b > 0) A[b][b] += 1, A[b][a] -= 1;
    if (c == 0) {
      A.emplace_back(n + 1);
      A.back()[a] = +1;
      A.back()[b] = -1;
    }
  }
  for (int i = 0; i < n; ++i) {
    if (!D.Same(0, i)) {
      A.emplace_back(n + 1);
      A.back()[i] = 1;
      A.back().back() = 0;
    }
  }
  auto pi = SolveLinear(A);
  if (pi.empty()) { cout << 0 << endl; return 0; }
  ld ans = 1e18;
  for (auto itr : cons) {
    int a, b, c; tie(a, b, c) = itr;
    if (abs(pi[b] - pi[a]) < EPS) continue;
    ans = min(ans, c / abs(pi[b] - pi[a]));
  }
  cout << fixed << setprecision(3) << ans << endl;

  return 0;
}