Pagini recente » Cod sursa (job #3216538) | Cod sursa (job #1960959) | Cod sursa (job #807238) | Cod sursa (job #1312660) | Cod sursa (job #477611)
Cod sursa(job #477611)
// Flux maxim de cost minim.cpp : Defines the entry point for the console application.
//
//#include "stdafx.h"
#include "stdio.h"
#include "string.h"
FILE *ff=fopen("fmcm.in", "r");
FILE *g=fopen("fmcm.out", "w");
int n, m, s, d;
int sum;
int cap[351][351];
int flux[351][351];
int ccost[351][351];
// variabile graf rezidual
int grez[351][351][2];
int countrez[351];
int heap[351];
int poz[351];
int vpoz[351];
int vizz[351];
int ant[351];
int antdef[351];
// variabile bellman-ford
int matbf[351][351][2];
int countbf[351];
int coada[10000];
int sol[351];
int incd[351];
void bellmanford()
{
for (int j=1; j<=n; ++j)
sol[j]=10000000;
sol[s]=0;
int i=1, cd=1;
coada[1]=s;
for (i=1; i<=cd; ++i)
{
int cv=coada[i];
for (int k=1; k<=countbf[cv]; ++k)
{
int auxy=matbf[cv][k][0];
int auxcost=matbf[cv][k][1];
if (sol[auxy]>sol[cv]+auxcost)
sol[auxy]=sol[cv]+auxcost;
if (!incd[auxy])
{
coada[++cd]=auxy;
incd[auxy]=1;
}
}
incd[cv]=0;
}
}
void init()
{
for (int i=1; i<=n; ++i)
for (int j=1; j<=countbf[i]; ++j)
{
int y=grez[i][j][0];
grez[i][j][1]+=sol[i]-sol[y];
grez[y][++countrez[y]][0]=i;
grez[y][countrez[y]][1]=-grez[i][j][1];
cap[y][i]=0;
}
}
void swap(int i, int j)
{
int h=heap[i]; heap[i]=heap[j]; heap[j]=h;
h=poz[i]; poz[i]=poz[j]; poz[j]=h;
vpoz[poz[i]]=i; vpoz[poz[j]]=j;
}
void upheap(int x)
{
int tata=x/2;
int fiu=x;
while (heap[tata]>heap[fiu] && tata>0)
{
swap(tata, fiu);
fiu=tata;
tata=fiu/2;
}
}
void downheap(int x)
{
int tata=x;
int fiu=x*2;
if (fiu<heap[0] && heap[fiu]>heap[fiu+1]) fiu++;
while (heap[tata]>heap[fiu])
{
swap(tata, fiu);
tata=fiu;
fiu=tata*2;
if (fiu<heap[0] && heap[fiu]>heap[fiu+1]) fiu++;
}
}
int dijkstra()
{
heap[0]=0;
poz[0]=0;
memset(vizz, 0, sizeof(vizz));
for (int i=1; i<=n; i++)
{
if (i!=s)
{
heap[++heap[0]]=1000000;
poz[++poz[0]]=i;
vpoz[i]=poz[0];
}
}
int cr=s;
int sum=0;
while (vizz[d]!=1 && heap[0]>=0 && sum<1000000)
{
antdef[cr]=ant[cr];
vizz[cr]=1;
if (vizz[d]==1)
{
antdef[cr]=ant[cr];
return 1;
}
for (int j=1; j<=countrez[cr]; ++j)
{
int y=grez[cr][j][0];
int cost=grez[cr][j][1];
int c=cap[cr][y];
int f=flux[cr][y];
if (!vizz[y] && sum+cost<heap[vpoz[y]] && c>f)
{
ant[y]=cr;
heap[vpoz[y]]=sum+cost;
upheap(vpoz[y]);
}
}
if (heap[0]>0)
{
cr=poz[1];
sum=heap[1];
heap[1]=heap[heap[0]];
poz[1]=poz[heap[0]];
vpoz[poz[1]]=1;
heap[0]--;
downheap(1);
}
}
if (vizz[d]==1)
{
antdef[cr]=ant[cr];
return 1;
}
return 0;
}
int minim(int x, int y)
{
if (x>y) return y;
return x;
}
void program()
{
while (dijkstra())
{
int fflux=1000000000;
int auxc=0;
int aux=d;
while (aux!=s)
{
fflux=minim(fflux, cap[antdef[aux]][aux]-flux[antdef[aux]][aux]);
auxc+=ccost[antdef[aux]][aux];
aux=antdef[aux];
}
sum+=fflux*auxc;
aux=d;
while (aux!=s)
{
flux[antdef[aux]][aux]+=fflux;
flux[aux][antdef[aux]]-=fflux;
aux=antdef[aux];
}
}
fprintf(g, "%d", sum);
}
void read()
{
fscanf(ff, "%d%d%d%d", &n, &m, &s, &d);
for (int i=1; i<=m; ++i)
{
int x, y, c, cost;
fscanf(ff, "%d%d%d%d", &x, &y, &c, &cost);
matbf[x][++countbf[x]][0]=y;
matbf[x][countbf[x]][1]=cost;
grez[x][++countrez[x]][0]=y;
grez[x][countrez[x]][1]=cost;
cap[x][y]=c;
ccost[x][y]=cost;
}
}
int main()
{
read();
bellmanford();
init();
program();
return 0;
}