Cod sursa(job #3359613)

Utilizator rares89_Dumitriu Rares rares89_ Data 1 iulie 2026 00:58:41
Problema Flux Scor 100
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.76 kb
#include <bits/stdc++.h>

using namespace std;

ifstream fin("flux.in");
ofstream fout("flux.out");

const double EPS = 1e-12;

struct Edge {
    int x, y;
    double c;
};

int n, m, cnt;
vector<Edge> edges;
vector<int> G[105];
int viz[105], id[105];
double a[105][105], b[105], val[105];

void dfs(int node) {
    viz[node] = 1;

    for (int edge : G[node]) {
        int to = edges[edge].x + edges[edge].y - node;

        if (!viz[to])
            dfs(to);
    }
}

int main() {
    fin >> n >> m;

    for (int i = 0; i < m; ++i) {
        int x, y;
        double c;

        fin >> x >> y >> c;

        edges.push_back({x, y, c});
        G[x].push_back(i);
        G[y].push_back(i);
    }

    dfs(1);

    for (int i = 2; i < n; ++i) {
        if (viz[i])
            id[i] = ++cnt;
    }

    for (auto edge : edges) {
        int x = edge.x;
        int y = edge.y;

        if (!viz[x] || !viz[y])
            continue;

        if (x != 1 && x != n) {
            ++a[id[x]][id[x]];

            if (y != 1 && y != n)
                --a[id[x]][id[y]];
            else if (y == 1)
                ++b[id[x]];
        }

        if (y != 1 && y != n) {
            ++a[id[y]][id[y]];

            if (x != 1 && x != n)
                --a[id[y]][id[x]];
            else if (x == 1)
                ++b[id[y]];
        }
    }

    for (int i = 1; i <= cnt; ++i) {
        int pos = i;

        for (int j = i; j <= cnt; ++j) {
            if (abs(a[j][i]) > abs(a[pos][i]))
                pos = j;
        }

        for (int j = i; j <= cnt; ++j)
            swap(a[i][j], a[pos][j]);

        swap(b[i], b[pos]);

        for (int j = i + 1; j <= cnt; ++j) {
            double coef = a[j][i] / a[i][i];

            for (int k = i; k <= cnt; ++k)
                a[j][k] -= coef * a[i][k];

            b[j] -= coef * b[i];
        }
    }

    val[1] = 1;
    val[n] = 0;

    for (int i = n - 1; i >= 2; --i) {
        if (!viz[i])
            continue;

        val[i] = b[id[i]];

        for (int j = i + 1; j < n; ++j) {
            if (viz[j])
                val[i] -= a[id[i]][id[j]] * val[j];
        }

        val[i] /= a[id[i]][id[i]];
    }

    double total = 0;
    double scale = 1e100;

    for (auto edge : edges) {
        int x = edge.x;
        int y = edge.y;

        if (!viz[x] || !viz[y])
            continue;

        double flow = abs(val[x] - val[y]);

        if (x == 1)
            total += val[x] - val[y];

        if (y == 1)
            total += val[y] - val[x];

        if (flow > EPS)
            scale = min(scale, edge.c / flow);
    }

    fout << fixed << setprecision(3) << total * scale << "\n";

    return 0;
}