Cod sursa(job #1005760)

Utilizator sleepaholicNeculaescu Theodor sleepaholic Data 5 octombrie 2013 18:51:27
Problema Flux Scor 100
Compilator cpp Status done
Runda Lista lui wefgef Marime 1.78 kb
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <vector>
#include <cassert>
#define v first
#define c second
using namespace std;
typedef vector< pair<int, int> >::iterator it;
const int MaxN = 105;
const double Eps = 1e-8;
const double oo = 1e6;
vector< pair<int, int> > G[MaxN];
int N, M;
vector<double> A[MaxN];
double Flow[MaxN], Sol;
inline void Reduce(vector<double> &L1, vector<double> &L2, double C) {
for (int i = 1; i <= M+1; ++i)
L1[i] += C*L2[i];
}
void Gauss() {
int i = 1, j = 1;
while (i <= N && j <= M) {
int k;
for (k = i; k <= N && abs(A[k][j]) < Eps; ++k);
if (k == N+1) {
++j; continue;
}
swap(A[i], A[k]);
for (k = 1; k <= N; ++k)
if (i != k)
Reduce(A[k], A[i], -A[k][j]/A[i][j]);
++i, ++j;
}
}
void BuildFlow() {
for (int i = 1, j; i <= N; ++i) {
for (j = 1; j <= M && abs(A[i][j]) < Eps; ++j);
if (j <= M)
Flow[j] = A[i][M+1]/A[i][j];
}
}
void FindSol() {
double C = oo;
for (int x = 1; x <= N; ++x)
for (it y = G[x].begin(); y != G[x].end(); ++y)
C = min(C, abs((1.0*y->c)/(Flow[y->v]-Flow[x])));
for (int x = 1; x <= N; ++x)
Flow[x] *= C;
for (it y = G[N].begin(); y != G[N].end(); ++y)
Sol += Flow[N]-Flow[y->v];
}
void Solve() {
Gauss();
BuildFlow();
FindSol();
}
void Read() {
assert(freopen("flux.in", "r", stdin));
int NE; assert(scanf("%d %d", &N, &NE) == 2);
M = N;
for (int i = 1; i <= N; ++i)
A[i].resize(M+2, 0.0);
for (; NE > 0; --NE) {
int x, y, c; assert(scanf("%d %d %d", &x, &y, &c) == 3);
G[x].push_back(make_pair(y, c)), G[y].push_back(make_pair(x, c));
if (x != 1)
++A[x][y], --A[x][x];
if (y != 1)
++A[y][x], --A[y][y];
}
A[N][M+1] = -1.0;
}
void Print() {
assert(freopen("flux.out", "w", stdout));
printf("%.8lf\n", Sol);
}
int main() {
Read();
Solve();
Print();
return 0;
}