Cod sursa(job #718499)

Utilizator Addy.Adrian Draghici Addy. Data 20 martie 2012 20:46:01
Problema Flux Scor 92
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.43 kb
#include <cstdio>
#include <algorithm>
#include <vector>

using namespace std;

#define NMAX 105
#define MMAX 5005
#define EPS 0.00000001
#define INF (1LL << 60)

struct edge {
	
	int a, b, c;
};

bool U[NMAX];
int N, M;
double A[NMAX][NMAX], X[NMAX];
edge E[MMAX];
vector <int> G[NMAX];

bool zero (double), gauss ();
void swap_lines (int, int), dfs (int), equations (), input (), output ();
double compute ();

int main () {
	
	input ();
	
	output ();
	
	return 0;
}

double compute () {
	
	dfs (1);
	if (!U[N]) return 0;
	
	equations ();
	
	if (!gauss ()) return 0;
	
	double flow, sol = INF; int a, b; double c;
	for (int i = 1; i <= M; i++) {
		a = E[i].a, b = E[i].b, c = E[i].c;
		flow = X[a] - X[b]; if (flow < 0) flow = -flow;
		sol = min (sol, c / flow);
	}
	
	return sol;
}

void dfs (int nod) {
	
	U[nod] = 1;
	for (vector <int>::iterator it = G[nod].begin (); it != G[nod].end (); it++)
		if (!U[*it])
			dfs (*it);
}

void equations () {
	
	int i, a, b;
	for (i = 1; i <= M; i++) {
		a = E[i].a, b = E[i].b;
		A[a][a]++, A[a][b]--;
		A[b][b]++, A[b][a]--;
	}
	
	A[1][1] = 1; A[N][N + 1] = 1;
	for (i = 2; i < N; i++) A[1][i] = 0;
}

bool gauss () {
	
	int i, j, k, t, p;
	for (i = 1, j = 1; i <= N && j <= N; j++) {
		
		for (k = i; k <= N; k++)
			if (!zero (A[k][j])) break;
		
		if (k == N + 1) continue;
		
		if (i != k) swap_lines (i, k);
		
		for (t = j + 1; t <= N + 1; t++) A[i][t] /= A[i][j];
		A[i][j] = 1;
		
		for (t = i + 1; t <= N; t++) {
			for (p = j + 1; p <= N + 1; p++)
				A[t][p] -= A[t][j] * A[i][p];
			A[t][j] = 0;
		}
		
		i++;
	}
	
	for (i = N; i > 0; i--)
		for (j = 1; j <= N + 1; j++)
			if (!zero (A[i][j])) {
				
				if (j == N + 1) return 0;
				
				X[j] = A[i][N + 1];
				for (k = j + 1; k <= N; k++)
					X[j] -= X[k] * A[i][k];
				
				break;
			}
	
	return 1;
}

bool zero (double x) {
	
	if (x < 0) x = -x;
	
	if (x < EPS) return 1;
	return 0;
}

void swap_lines (int a, int b) {
	
	for (int i = 1; i <= N + 1; i++) swap (A[a][i], A[b][i]);
}

void input () {
	
	freopen ("flux.in", "r", stdin);
	
	scanf ("%d %d", &N, &M);
	
	int i, x, y, c;
	for (i = 1; i <= M; i++) {
		scanf ("%d %d %d", &x, &y, &c);
		G[x].push_back (y);
		G[y].push_back (x);
		E[i].a = x, E[i].b = y, E[i].c = c;
	}
}

void output () {
	
	freopen ("flux.out", "w", stdout);
	
	printf ("%.3lf\n", compute ());
}