Cod sursa(job #109976)

Utilizator wefgefAndrei Grigorean wefgef Data 25 noiembrie 2007 15:04:57
Problema Tunelul groazei Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.53 kb
/*
 	Author : Andrei Grigorean
	Time Complextity : O(N^3 + M)
	Memory Complexity : O(N^2 + M)
*/

#include <cstdio>
#include <cassert>
#include <vector>
#include <algorithm>
using namespace std;

#define pb push_back
#define sz(c) int((c).size())
#define mp make_pair
#define x first
#define y second
#define tr(it, c) for (typeof((c).begin()) it = (c).begin(); it != (c).end(); ++it)

const int Nmax = 256;

int N, M;
vector< pair<int, int> > G[Nmax];
double A[Nmax][Nmax], B[Nmax];

void ReadData() {
	freopen("tunel.in", "r", stdin);
	freopen("tunel.out", "w", stdout);

	scanf("%d %d", &N, &M);
	assert(1 < N && N < 256);
	assert(N-1 <= M && M <= 100000);
	for (int i = 0; i < M; ++i) {
		int a, b, c;
		scanf("%d %d %d", &a, &b, &c);

		assert(a > 0 && a <= N);
		assert(b > 0 && b <= N);
		assert(c > 0 && c < 1000);

		G[a].pb( mp(b, c) );
		G[b].pb( mp(a, c) );
	}
}

void Build_system() {
	for (int i = 1; i < N; ++i) {
		A[i][i] = 1;

		double coef = (double)1/sz(G[i]);

		tr(it, G[i]) {
			A[i][it->x] -= coef;
			B[i] += coef * it->y;
		}
	}
	A[N][N] = 1; B[N] = 0;
}

void Gauss() {
	for (int j = 1; j <= N; ++j) {
		int i;
		for (i = j; i <= N; ++i)
			if (A[i][j]) break;
		
		for (int k = 1; k <= N; ++k)
			swap(A[j][k], A[i][k]);
		swap(B[i], B[j]);

		for (int i = 1; i <= N; ++i) if (i != j) {
			double raport = -A[i][j]/A[j][j];

			for (int k = 1; k <= N; ++k)
				A[i][k] += raport * A[j][k];
			B[i] += raport * B[j];
		}
	}
	printf("%lf\n", B[1]/A[1][1]);
}

void Solve() {
	Build_system();
	Gauss();
}

int main() {
	ReadData();
	Solve();
}