Cod sursa(job #3221111)

Utilizator not_anduAndu Scheusan not_andu Data 5 aprilie 2024 22:30:02
Problema Tunelul groazei Scor 100
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 1.76 kb
#include <bits/stdc++.h>

using namespace std;

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

const int N_MAX = 260;
const int M_MAX = 1e5 + 5;
const double EPS = 1e-6;

struct Node {

    int node;
    int cost;

    Node() {}
    Node(int _node, int _cost) : node(_node), cost(_cost) {}

};

int nodes, edges;
vector<Node> adj[N_MAX];
double gauss[N_MAX][N_MAX];

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

void solve(){

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

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

    for(int node = 1; node <= nodes; ++node){
        if(equalToZero(gauss[node][node])) {
            int i = node + 1;
            while(equalToZero(gauss[node][i])) ++i;
            swap(gauss[node], gauss[i]);
        }
        for(int i = 1; i <= nodes; ++i){
            if(node == i) continue; // diagonala
            double mult = gauss[i][node] / gauss[node][node];
            for(int j = 1; j <= nodes + 1; ++j){
                gauss[i][j] -= mult * gauss[node][j];
            }
        }
    }

    cout << fixed << setprecision(4) << (gauss[1][nodes + 1] / gauss[1][1]) << '\n';

}

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