Cod sursa(job #3243458)

Utilizator not_anduAndu Scheusan not_andu Data 18 septembrie 2024 18:48:27
Problema Flux Scor 100
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.32 kb
#include <bits/stdc++.h>

using namespace std;

#define INFILE "flux.in"
#define OUTFILE "flux.out"

const int N_MAX = 100;
const int M_MAX = 5e3;
const double EPS = 1e-9;

struct Node {

public:
    int node, capacity;

    Node() {}
    Node(int _node, int _capacity) : node(_node), capacity(_capacity) {}

};

int nodes, edges;
bool visited[N_MAX + 5];
vector<Node> adj[N_MAX + 5];

double flow = 0;
double distanta[N_MAX + 5];
double gauss[N_MAX + 5][N_MAX + 5];

bool isZero(double number){
    return (-EPS < number && number < EPS);
}

void dfs(int node){
    visited[node] = true;
    for(auto &to : adj[node]){
        if(!visited[to.node]){
            dfs(to.node);
        }
    }
}

void solve(){

    cin >> nodes >> edges;
    for(int i = 0; i < edges; ++i){
        int node1, node2, capa; cin >> node1 >> node2 >> capa;
        adj[node1].push_back(Node(node2, capa));
        adj[node2].push_back(Node(node1, capa));
    }

    dfs(1);

    if(!visited[nodes]){
        cout << fixed << setprecision(3) << 0 << '\n';
    }
    else {

        gauss[1][1] = 1.0;
        for(int i = 2; i < nodes; ++i){
            gauss[i][i] = adj[i].size();
            for(auto &to : adj[i]){
                gauss[i][to.node] -= 1.0;
            }
        }
        gauss[nodes][nodes] = gauss[nodes][nodes + 1] = 1.0;

        for(int i = 1; i <= nodes; ++i){
            if(!isZero(gauss[i][i])){
                for(int j = 1; j <= nodes; ++j){
                    if(i == j) continue;
                    double raport = gauss[j][i] / gauss[i][i];
                    for(int k = 1; k <= nodes + 1; ++k) gauss[j][k] -= gauss[i][k] * raport;
                }
            }
        }

        for(int i = 1; i <= nodes; ++i){
            distanta[i] = gauss[i][nodes + 1] / gauss[i][i];
        }

        double raport = 0.0;
        for(int i = 1; i <= nodes; ++i){
            for(auto &to : adj[i]){
                raport = max(raport, (distanta[to.node] - distanta[i]) / to.capacity);
            }
        }
        
        for(auto &it : adj[nodes]) flow += (distanta[nodes] - distanta[it.node]) / raport;

        cout << fixed << setprecision(3) << flow << '\n';

    }
    
}

int main(){
    ios_base::sync_with_stdio(false);
    cin.tie(0), cout.tie(0);
    freopen(INFILE, "r", stdin);
    freopen(OUTFILE, "w", stdout);
    solve();
    return 0;
}