Cod sursa(job #1865710)

Utilizator alex_HarryBabalau Alexandru alex_Harry Data 1 februarie 2017 23:29:04
Problema Flux Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.77 kb
#include <fstream>
#include <vector>
#include <iomanip>
using namespace std;
ifstream f("flux.in");
ofstream g("flux.out");
const int NMax = 105;
int N, M;
const double eps = 0.000001;
vector <pair <int, int> > G[NMax];
double A[NMax][NMax];
double S[NMax];
bool Use[NMax];
void Read()
{
    f >> N >> M;
    for(int i = 1; i <= M; i++)
    {
        int x, y, c;
        f >> x >> y >> c;
        G[x].push_back(make_pair(y, c));
        G[y].push_back(make_pair(x, c));
    }
}

void buildA()
{
    A[1][1] = 1.0;
    for(int i = 2; i < N; i++)
    {
        A[i][i] = (double)G[i].size();
        for(int j = 0; j < G[i].size(); j++)
        {
            int neighb = G[i][j].first;
            A[i][neighb] -= 1.0;
        }
    }
    A[N][N] = A[N][N + 1] = 1.0;
}

void Solve()
{
    int i = 1, j = 1;
    while(i <= N && j <= N)
    {
        int k;
        for(k = i; k <= N && A[k][j] < eps && A[k][j] >= -eps; k++);
        if(k == N + 1)
        {
            i++;
            j++;
            continue;
        }
        if(k != i)
            swap(A[k], A[i]);
        for(int l = j + 1; l <= N + 1; l++)
            A[i][l] /= A[i][j];
        A[i][j] = 1.0;
        for(k = i + 1; k <= N; k++)
        {
            for(int l = j + 1; l <= N + 1; l++)
                A[k][l] -= A[k][j] * A[i][l];
            A[k][j] = 0;
        }
        ++i;
        ++j;
    }
    for(int i = N; i >= 1; i--)
    {
        int j;
        for(j = 1; j <= N && A[i][j] < eps && A[i][j] > -eps; j++);
        double sum = 0;
        //S[j] = A[i][N + 1];
        if(j == N + 1)
            continue;
        for(int k = j + 1; k <= N; k++)
            sum += S[k] * A[i][k];
        S[i] = (A[i][N + 1] - sum) / A[i][i];
    }
}

void DFS(int node)
{
    Use[node] = 1;
    for(int i = 0; i < G[node].size(); i++)
    {
        int neighb = G[node][i].first;
        if(Use[neighb] == 0)
            DFS(neighb);
    }
}
inline double mod(double x)
{
    return max(x, -x);
}
void findAns()
{
    double Min = 1000000000;
    for(int i = 1; i <= N; i++)
    {
        if(Use[i] == 0)
            continue;
        for(int j = 0; j < G[i].size(); j++)
        {
            int neighb = G[i][j].first, c = G[i][j].second;
            double e = mod((double) c / (S[i] - S[neighb]));
            Min = min(Min, e);
        }
    }
    double ans = 0;
    for(int i = 0; i < G[N].size(); i++)
    {
        int neighb = G[N][i].first;
        ans += (S[N] - S[neighb]) * Min;
    }
    g << fixed << setprecision(15) << ans << "\n";
}
int main()
{
    Read();
    DFS(1);
    if(Use[N] == 0)
    {
        g << "0.000\n";
        return 0;
    }
    buildA();
    Solve();
    findAns();
    return 0;
}