Cod sursa(job #804682)

Utilizator Marius96Marius Gavrilescu Marius96 Data 30 octombrie 2012 07:49:01
Problema Tunelul groazei Scor 50
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.63 kb
#include<cstdlib>
#include<cstdio>
#include<algorithm>
#include<vector>
using std::vector;
using std::swap;

struct str
{
	int x,c;

	str()
		{
			x=c=0;
		}

	str (int xx,int cc)
		{
			x=xx;
			c=cc;
		}
};

vector<str> v[260];

double g[230][230];
double r[230];

int n;

double gauss()
{
	int i=0,j=0;
	while(i<n&&j<n){
		for(int x=i;x<n;x++)
			if(g[x][j]){
				for(int y=0;y<=n;y++){
					double t=g[x][y];
					g[x][y]=g[i][y];
					g[i][y]=t;
				}
				double val=g[i][j];
				for(int y=0;y<=n;y++)
					g[i][y]/=val;
				for(int u=i+1;u<n;u++){
					val=g[u][j];
					for(int y=0;y<=n;y++)
						g[u][y]-=g[i][y]*val;
				}
				i++;
				break;
			}
		j++;
	}

	for(int i=n-1;i>=0;i--){
		int p;
		for(p=0;p<=n;p++)
			if(g[i][p]>1e-10 || g[i][p]<-1e-10)
				break;
		if(p==n){
			abort();
		} else if (p>n)
			continue; //???
		r[p]=g[i][n];
		for(int j=n-1;j>p;j--)
			r[p]-=g[i][j]*r[j];
	}
#ifdef DUMMY_GAUSS
	for(int i=0;i<n;i++)
		printf ("%lf ",r[i]);
#endif
	return r[0];
}

int main()
{
	freopen ("tunel.in","r",stdin);

	freopen ("tunel.out","w",stdout);

#ifdef DUMMY_GAUSS
	n=3;
	g[0][0]=2,g[0][1]=1,g[0][2]=-1,g[0][3]=8;
	g[1][0]=-3,g[1][1]=-1,g[1][2]=2,g[1][3]=-11;
	g[2][0]=-2,g[2][1]=1,g[2][2]=2,g[2][3]=-3;
	gauss();
	return 0;
#endif
	int ne;
	scanf ("%d%d",&n,&ne);
	for(int i=0;i<ne;i++){
		int a,b,c;
		scanf ("%d%d%d",&a,&b,&c);
		a--,b--;
		v[a].push_back (str (b,c));
		v[b].push_back (str (a,c));
	}

	for(int i=0;i<n-1;i++){
		g[i][i]=1;
		for(vector<str>::iterator it=v[i].begin();it!=v[i].end();it++)
			g[i][it->x]+=-1.0/v[i].size(),g[i][n]+=it->c;
		g[i][n]/=v[i].size();
	}
	g[n-1][n-1]=1;

	printf ("%.4lf",gauss());
	return 0;
}