Cod sursa(job #6262)

Utilizator rusRus Sergiu rus Data 18 ianuarie 2007 16:54:41
Problema Cc Scor 0
Compilator cpp Status done
Runda Arhiva de probleme Marime 4.12 kb
#include <fstream.h>
#include <iomanip.h>

#include <math.h>

ofstream fout ( "cc.out" );

#define FIN "cc.in"
#define FOUT "cc.out"
#define DIM 101
#define INFINIT 3000
typedef struct nod{
               int info;
               nod*urm;
               }*PNOD,NOD;
PNOD l[1001];

typedef int GRAF[DIM][DIM];
GRAF c, f, cost,a;   // capacit, flux, cost
int d[DIM];        // distanta (costul) minima de la sursa la toate celelelte
int n, m, ok;          // noduri muchii
int sursa, dest;
int tata[DIM];     // retine nodurile de pe drumul de  crestere
int flow;          // flux maxim de cost minim

void ReadNetwork();
int BellmanFord();
void add(int ,int ,int );
void MinCostFlow();
void WriteMinCostFlow();

int main()
{
	ReadNetwork();
	MinCostFlow();
	//fout<< flow;
	WriteMinCostFlow();

	return 0;
}

void ReadNetwork()
{
	ifstream fin(FIN);
	int i,j;
    fin >>n;
	int v1, v2, costul;
	for (i = 1; i <= n; i++ )
	{
		for(j=1;j<=n;j++)

		fin>>a[i][j];
                

	}

	sursa=0;
	dest=2*n+1;
	for(i=1;i<=n;i++)
	{
                     c[sursa][i]=1;
                     cost[sursa][i]=0;
                     add(sursa,i);
                     
    } 
    
    for(i=1;i<=n;i++)
    {
                    for(j=n+1;j<=n+n;j++)
                    {
                                         c[i][j]=1;
                                         cost[i][j]=a[i][j-n];
                                         add(i,j-n);
                    }
    }
    for(i=n+1;i<=2*n+1;i++)
    {
                           c[i][2*n+1]=1;
                           cost[i][2*n+1]=0;
                           add(i,2*n+1);
    }                           
    
    
    fin.close();
}

void add(int i,int j)
{
     PNOD p=new NOD;
     p->info=j;
     p->urm=l[i];
     l[i]=p;
}
int Minimizeaza()
{
	ok = 0;
	for ( int i = 0; i <= 2 * n+1; i++ )
		for ( int j =0; j <= 2 * n+1; j++ )
		{
			if ( c[i][j] > f[i][j]) // arc nesaturat
				if ( d[j] > d[i] + cost[i][j] )
				{
					d[j] = d[i] + cost[i][j];
					tata[j] = i;
					ok = 1;
				}

			if ( f[j][i] > 0 )
				if ( d[j] > d[i] - cost[i][j] )
				{
					d[j] = d[i] - cost[j][i];
					tata[j] = -i;
					ok = 1;
				}
		}

	return ok;
}

int BellmanFord()
{
    int i = 0;
	for ( i = 1; i <= 2 * n + 1; i++ )
	{
		tata[i] = -INFINIT;
		d[i] = INFINIT;
	}

	d[sursa] = 0;

	for (i = 1; i <= n - 1; i++)
		Minimizeaza();


	if ( d[dest] == INFINIT )
		return 0;
	return 1;

}


void Augment()
{
	int i = dest;
	int j;

	while ( i )
	{
		j = abs(tata[i]);
		if ( tata[i] >= 0 ) 
			f[j][i]++;
		else
			f[i][j]--;
		i = j;
	}
 }

void MinCostFlow()
{
	for ( flow = 0; BellmanFord(); flow++ )  //la fiecare drum de crestere gasit, cresc fluxul cu o unitate
		Augment();
}


void WriteMinCostFlow ()                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       
{
	ofstream fout(FOUT);
	//fout << flow  << '\n';
	int i, j,sol=0;

	for ( i = 1; i <= n; i++ )
	{
		for ( j = n + 1; j <= n +  n; j++ )
			if(f[i][j])
			sol+=cost[i][j];
			//fout << setw(4) << f[i][j];
		//fout << endl;
	}

	fout<<sol;
	fout.close();
}