Cod sursa(job #800049)

Utilizator ChallengeMurtaza Alexandru Challenge Data 20 octombrie 2012 17:14:48
Problema Flux Scor 12
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.9 kb
/*
	PROB: flux
	LANG: C++
*/

#include <fstream>
#include <iostream>
#include <iomanip>
#include <vector>
#include <cstdio>

//#define DEBUG

#ifndef DEBUG
	#define PRINT(x)
	#define D if(0)
#else
	#define PRINT(x) \
		cout<<#x<<":\t"<<x<<endl
	#define D if(1)
#endif

using namespace std;

const char InFile[]="flux.in";
const char OutFile[]="flux.out";
const int MaxN=128;
const int MaxM=5012;
const double EPS=1e-5;
const double DINF=1e30;

ifstream fin(InFile);

struct Edge
{
	int x,y;
	double c;
};

int N,M,x,y,viz[MaxN],i,j;
double c,sol,A[MaxN][MaxN],SOL[MaxN];
Edge E[MaxM];
vector<int> G[MaxN];
FILE *fout=fopen(OutFile,"w");

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

inline double myabs(const double &x)
{
	if(x<0)
	{
		return -x;
	}
	return x;
}

inline double mymin(const double &x, const double &y)
{
	if(x<y)
	{
		return x;
	}
	return y;
}

inline bool equal(const double &x, const double &y)
{
	return myabs(x-y)<EPS;
}

int main()
{
	fin>>N>>M;
	for(register int i=1;i<=M;++i)
	{
		fin>>x>>y>>c;
		G[x].push_back(y);
		G[y].push_back(x);
		E[i].x=x;
		E[i].y=y;
		E[i].c=c;
	}
	fin.close();

	goto afis;

	DFS(1);
	
	if(!viz[N])
	{
		goto afis;
	}

	for(register int i=1;i<=M;++i)
	{
		int &x=E[i].x;
		int &y=E[i].y;
		if(x!=1)
		{
			++A[x][x];
			--A[x][y];
		}
		if(y!=1)
		{
			++A[y][y];
			--A[y][x];
		}
	}
	A[1][1]=1;
	A[N][N+1]=1;

D
{
	for(register int i=1;i<=N;++i)
	{
		for(register int j=1;j<=N+1;++j)
		{
			cout<<A[i][j]<<" ";
		}
		cout<<"\n";
	}
	cout<<"gauss:\n";
}

	i=j=1;
	while(i<=N && j<=N)
	{
		int k=i;
		for(;k<=N;++k)
		{
			if(!equal(A[k][j],0))
			{
				break;
			}
		}

		if(k==N+1)
		{
			++j;
			continue;
		}

		if(k!=i)
		{
			for(register int c=1;c<=N+1;++c)
			{
				swap(A[i][c],A[k][c]);
			}
		}

		for(register int c=j+1;c<=N+1;++c)
		{
			A[i][c]/=A[i][j];
		}
		A[i][j]=1;

		for(register int l=i+1;l<=N;++l)
		{
			for(register int c=j+1;c<=N+1;++c)
			{
				A[l][c]-=A[i][c]*A[l][j];
			}
			A[l][j]=0;
		}

		++i;
		++j;
	}

	for(register int i=N;i>0;--i)
	{
		for(register int j=1;j<=N+1;++j)
		{
			if(!equal(A[i][j],0))
			{
				if(j==N+1)
				{
					//goto afis;
				}
				SOL[j]=A[i][N+1];
				for(register int k=j+1;k<=N;++k)
				{
					SOL[j]-=SOL[k]*A[i][k];
				}
				break;
			}
		}
	}

D
{
	cout<<fixed<<setprecision(3);
	for(register int i=1;i<=N;++i)
	{
		for(register int j=1;j<=N+1;++j)
		{
			cout<<A[i][j]<<" ";
		}
		cout<<"\n";
	}
	cout<<"SOLS=\n";
	for(register int i=1;i<=N;++i)
	{
		cout<<SOL[i]<<" ";
	}
	cout<<"\n";
}

	sol=DINF;
	for(register int i=1;i<=M;++i)
	{
		PRINT(i<<" "<<E[i].x<<" "<<E[i].y<<" "<<E[i].c);
		int &x=E[i].x;
		int &y=E[i].y;
		double &c=E[i].c;
		PRINT(x<<" "<<y<<" "<<c<<" "<<SOL[x]<<" "<<SOL[y]<<" "<<myabs(SOL[x]-SOL[y]));
		sol=mymin(sol,c/myabs(SOL[x]-SOL[y]));
	}

afis:
	fprintf(fout,"%.6lf",sol);
	fclose(fout);
	return 0;
}