Cod sursa(job #801736)

Utilizator a_h1926Heidelbacher Andrei a_h1926 Data 24 octombrie 2012 21:17:54
Problema Flux Scor 100
Compilator cpp Status done
Runda Lista lui wefgef Marime 2.04 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;
}