Pagini recente » Cod sursa (job #1529638) | Cod sursa (job #2675982) | Cod sursa (job #2801105) | Cod sursa (job #625938) | Cod sursa (job #2197481)
#include <fstream>
#include <vector>
#include <cstring>
using namespace std;
ifstream cin("fmcm.in");
ofstream cout("fmcm.out");
vector<int> v[400];
int cap[400][400];
int cost[400][400],t[400],dmin[400];
int h[400],hsize,newd[400],idx[400],aux[400];
int q[130000],viz[400];
int x,y,c,z,n,m,s,d,i,j,flux,costf;
int inf = 10000000;
int cmin = inf;
bool drum_minim(int s, int d)
{
memset(viz,0,sizeof(viz));
viz[s]=1;
int st = 1,en=1;
q[st] = s;
t[s]=-1;
dmin[s]=0;
for(int i=1; i<=n; ++i)
if(i!=s)
dmin[i]=inf;
while(st<=en)
{
int nod = q[st];
++st;
viz[nod]=0;
for(int i=0; i<v[nod].size(); ++i)
{
if(cap[nod][v[nod][i]] > 0
&& dmin[nod] + cost[nod][v[nod][i]] < dmin[v[nod][i]])
{
dmin[v[nod][i]] = dmin[nod] + cost[nod][v[nod][i]];
if(!viz[v[nod][i]])
{
++en;
q[en]=v[nod][i];
viz[v[nod][i]]=1;
}
t[v[nod][i]] = nod;
}
}
}
if(dmin[d] != inf) return 1;
return 0;
}
void downh()
{
int aux=1;
while(aux*2<=hsize)
{
int index=aux;
if(newd[h[2*aux]]<newd[h[aux]]) index=2*aux;
if(2*aux+1<=hsize)
if(newd[h[2*aux+1]]<newd[h[index]]) index=2*aux+1;
if(index==aux) break;
swap(idx[h[aux]],idx[h[index]]);
swap(h[aux],h[index]);
aux=index;
}
}
void uph(int x)
{
while(x>1 && newd[h[x/2]]>newd[h[x]])
{
swap(idx[h[x]],idx[h[x/2]]);
swap(h[x/2], h[x]);
x/=2;
}
}
bool exista_drum(int s, int d)
{
memset(aux,0,sizeof(aux));
memset(t,0,sizeof(t));
t[s]=-1;
for(int i=1; i<=n; ++i)
{
h[i]=i;
idx[i]=i;
newd[i]=inf;
}
newd[s]=0;
h[1]=s;
h[s]=1;
idx[s]=1;
idx[1]=s;
hsize=n;
while(hsize>0)
{
int nodc=h[1];
idx[h[hsize]]=1;
h[1]=h[hsize];
--hsize;
downh();
int costm = 0;
for(int i=0; i<v[nodc].size(); ++i)
{
if(cap[nodc][v[nodc][i]] > 0)
{
costm =dmin[nodc] + cost[nodc][v[nodc][i]] - dmin[v[nodc][i]] ;
if(newd [v[nodc][i]] > newd[nodc] + costm)
{
newd[v[nodc][i]] = newd[nodc] + costm;
t[v[nodc][i]] = nodc;
uph(idx[v[nodc][i]]);
aux[v[nodc][i]] = aux[nodc] + cost[nodc][v[nodc][i]];
}
}
}
}
return t[d]!=0;
}
int main()
{
cin>>n>>m>>s>>d;
for(i=1; i<=m; ++i)
{
cin>>x>>y>>c>>z;
v[x].push_back(y);
cap[x][y]=c;
cost[x][y]=z;
v[y].push_back(x);
cap[y][x]=0;
cost[y][x]=-z;
}
drum_minim(s,d);
int nod = d;
while(exista_drum(s,d))
{
for(i=1; i<=n; ++i)
dmin[i]=aux[i];
nod = d;
cmin = inf;
while(nod != s)
{
cmin = min(cmin,cap[t[nod]][nod]);
nod = t[nod];
}
flux += cmin;
costf += dmin[d]*cmin;
nod = d;
while(nod !=s)
{
cap[nod][t[nod]] += cmin;
cap[t[nod]][nod] -= cmin;
nod = t[nod];
}
}
cout<<costf;
return 0;
}