Cod sursa(job #718398)

Utilizator Addy.Adrian Draghici Addy. Data 20 martie 2012 19:26:26
Problema Flux Scor 72
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.32 kb
#include <cstdio>
#include <algorithm>

using namespace std;

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

using namespace std;

bool U[NMAX];
int V[NMAX][NMAX], C[NMAX][NMAX], N, M;
double A[NMAX][NMAX], X[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;
	for (int i = 1; i <= N; i++)
		for (int j = i + 1; j <= N; j++)
			if (V[i][j]) {
				flow = X[i] - X[j]; if (flow < 0) flow = -flow;
				sol = min (sol, C[i][j] / flow);
			}
	
	return sol;
}

void dfs (int nod) {
	
	U[nod] = 1;
	for (int i = 1; i <= N; i++)
		if (V[nod][i] && !U[i])
			dfs (i);
}

void equations () {
	
	int i, j;
	for (i = 1; i <= N; i++)
		for (j = 1; j <= N; j++)
			if (i != j) {
				A[i][i] += V[i][j];
				A[i][j] -= V[i][j];
			}
	
	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);
		V[x][y]++, V[y][x]++;
		C[x][y] = C[y][x] = c;
	}
}

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