Pagini recente » Borderou de evaluare (job #3326040) | Borderou de evaluare (job #343620) | Borderou de evaluare (job #443969) | Borderou de evaluare (job #1551806) | Cod sursa (job #3356167)
// 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-8;
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 << ZERO << "\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
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 = r; 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 = abs(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 = abs(dist[n] - dist[it.ft]);
rez += flux / k;
}
}
fout << setprecision(3) << fixed << rez;
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
*/