Cod sursa(job #648978)

Utilizator blustudioPaul Herman blustudio Data 14 decembrie 2011 21:39:49
Problema Flux maxim de cost minim Scor 20
Compilator cpp Status done
Runda Arhiva educationala Marime 2.88 kb
#include <fstream>
#include <vector>
#include <set>
#include <iostream>
using namespace std;

struct muchie
{
	int cost; //Costul pentru a ajunge de la A la B
	unsigned short int a; //Nodul A
	unsigned short int b; //Nodul B
};

#define INFINIT 0x3f3f3f

int flux_maxim;
int flux[351][351];
int capacitate[351][351];
unsigned int noduri[351]; //Costul pt. a ajunge la fiecare nod
vector<muchie> muchii; //Muchiile grafului
short int drum[351]; //Vector de tati al drumului minim
unsigned short int n; //Numarul de noduri
unsigned short int m; //Nr. de muchii
unsigned short int sursa, destinatie;
bool drum_ameliorare; //Daca mai exista drum de ameliorare;

inline int Dijkstra()
{
	bool relaxeaza = true;
	for (unsigned short int i = 0; i <= n; i++)
		noduri[i] = INFINIT; //Costul pt. a ajunge la restul nodurilor e infinit
	noduri[sursa] = 0; //Costul pt. a ajunge la sursa e 0
	for (unsigned short int i = 1; (i <= n) && (relaxeaza == true); i++)
	{
		//Parcurgem toate nodurile daca am avut vreo relaxare
		relaxeaza = false; //Presupunem ca nu se face nici o relaxare
		for (unsigned int j = 0; j < muchii.size(); j++) //Parcurgem toate muchiile
		{
			if (capacitate[muchii[j].a][muchii[j].b] > flux[muchii[j].a][muchii[j].b])
			{
				if ((noduri[muchii[j].a] + muchii[j].cost) < noduri[muchii[j].b])
				{
					//Relaxam muchiile
					noduri[muchii[j].b] = noduri[muchii[j].a] + muchii[j].cost;
					drum[muchii[j].b] = muchii[j].a;
					relaxeaza = true;
				}
			}
		}
	}
	short int nod_curent;
	if (noduri[destinatie] < INFINIT)
	{
		drum_ameliorare = true;
		int capacitate_reziduala = INFINIT;
		for (nod_curent = destinatie; nod_curent != sursa; nod_curent = drum[nod_curent])
			if (capacitate_reziduala > (capacitate[drum[nod_curent]][nod_curent] - flux[drum[nod_curent]][nod_curent]))
				capacitate_reziduala = capacitate[drum[nod_curent]][nod_curent] - flux[drum[nod_curent]][nod_curent];
		for (nod_curent = destinatie; nod_curent != sursa; nod_curent = drum[nod_curent])
		{
			flux[nod_curent][drum[nod_curent]] -= capacitate_reziduala;
			flux[drum[nod_curent]][nod_curent] += capacitate_reziduala;
		}
		return noduri[destinatie] * capacitate_reziduala;
	}
	else
	{
		drum_ameliorare = false;
		return 0;
	}
}
inline void fmcm()
{
    flux_maxim = 0;
	do {
		flux_maxim += Dijkstra();
	} while (drum_ameliorare == true);
}
inline void citire()
{
    ifstream fin("fmcm.in");
    int a, b, f, c;
    muchie l;
    fin >> n >> m >> sursa >> destinatie;
	for (unsigned int i = 1; i <= m ; i++)
	{
		fin >> a >> b >> f >> c;
        l.cost = c;
        l.a = a;
        l.b = b;
        muchii.push_back(l);
        l.b = a;
        l.a = b;
        l.cost = -c;
        muchii.push_back(l); //Muchia inversa
        capacitate[a][b] = f;
	}
    fin.close();
}
inline void scriere()
{
    ofstream fout("fmcm.out");
    fout << flux_maxim;
    fout.close();
}
int main()
{
    citire();
    fmcm();
    scriere();
    return 0;
}