Cod sursa(job #702855)

Utilizator andrei.finaruFinaru Andrei Emanuel andrei.finaru Data 2 martie 2012 09:41:10
Problema Flux maxim de cost minim Scor 20
Compilator cpp Status done
Runda Arhiva educationala Marime 2 kb
#include <fstream>
#include <vector>
#include <queue>
#include <cstring>
#include <algorithm>
#include <climits>

using namespace std;

int c,cmin,cp,n,m,x,y,minim,flux_maxim,s,d;
int cap[355][355],flux[355][355],tata[355],cost[355][355],cc[355],scost[355];
vector<int> lista[1001];
queue<int> coada;
char viz[1001];

ifstream f("fmcm.in");
ofstream g("fmcm.out");

int bmf()
{
    memset(viz,0,sizeof(viz));
    memset(tata,0,sizeof(tata));
    //fill(cc,INT_MAX,sizeof(cc));
    for(int i=1;i<=n;++i) cc[i]=INT_MAX;

	int x,i,nr_vecini,vecin;
	coada.push(s);
	tata[s]=-1;
	cc[s]=0;
	viz[s]=1;
   // g<<1<<' ';
	while(!coada.empty())
	{
		x=coada.front(); coada.pop();
		nr_vecini=lista[x].size();
		for(i=0;i<nr_vecini;i++)
		{
		    vecin=lista[x][i];
			if( (!viz[vecin] || cc[vecin]>cc[x]+cost[x][vecin]) && flux[x][vecin]<cap[x][vecin])
			{
			    if(!viz[vecin]) coada.push(vecin), viz[vecin]=1;
                cc[vecin]=cc[x]+cost[x][vecin];
				tata[vecin]=x;
				//g<<vecin<<' ';
			}
		}
	}
	//g<<" sfarsit_coada\n";
    return viz[d];
}

int main()
{
    int i,j;
	f>>n>>m>>s>>d;
	for(i=1;i<=m;i++)
	{
		f>>x>>y>>cp>>c;
		lista[x].push_back(y);
		lista[y].push_back(x);
		cost[x][y]=c;
		cost[y][x]=-c;
		cap[x][y]=cp;
	}

	while(bmf())
	{
	    //for(i=1;i<=n;++i) g<<cc[i]<<' ';
	    //g<<'\n'<<tata[d]<<'\n';
        minim=cap[tata[d]][d]-flux[tata[d]][d];
        for(j=tata[d];j!=s;j=tata[j])
            if(cap[tata[j]][j]-flux[tata[j]][j]<minim)
                minim=cap[tata[j]][j]-flux[tata[j]][j];

        //g<<minim<<' '<<cc[d]<<'\n';
        flux[tata[d]][d]+=minim;
        flux[d][tata[d]]-=minim;
        cmin+=minim*cc[d];

        for(j=tata[d];j!=s;j=tata[j])
        {
            flux[tata[j]][j]=flux[tata[j]][j]+ minim;
            flux[j][tata[j]]=flux[j][tata[j]]-minim;
        }
        //g<<" adaug la flux "<<minim<<'\n';
        flux_maxim=flux_maxim+minim;
	}
	g<<cmin<<'\n';
	f.close();g.close();
	return 0;
}