Pagini recente » Cod sursa (job #2421601) | Cod sursa (job #231014) | Cod sursa (job #835977) | Cod sursa (job #2482523) | Cod sursa (job #976678)
Cod sursa(job #976678)
#include<stdio.h>
#include<algorithm>
#include<cstring>
#include<vector>
#include<queue>
#define pb push_back
#define maxn 360
#define inf 0x3f3f3f3f
using namespace std;
int n,m,source,sink,flow,flowcost,nh;
int h[maxn],pos[maxn],oldd[maxn],reald[maxn],d[maxn],father[maxn];
int c[maxn][maxn],f[maxn][maxn],cost[maxn][maxn];
bool used[maxn];
vector <int> l[maxn];
void read()
{
int x,y,cap,cst;
scanf("%d%d%d%d",&n,&m,&source,&sink);
for(int i=1;i<=m;i++)
{
scanf("%d%d%d%d",&x,&y,&cap,&cst);
l[x].pb(y); l[y].pb(x);
c[x][y]=cap;
cost[x][y]=cst;
cost[y][x]=-cst;
}
}
void bellman()
{
int k;
queue <int> q;
memset(oldd,inf,sizeof(oldd)); oldd[source]=0;
for(q.push(source),used[source]=true;!q.empty();q.pop(),used[k]=false)
{
k=q.front();
for(unsigned int i=0;i<l[k].size();i++)
if( c[k][l[k][i]] && oldd[k]+cost[k][l[k][i]]<oldd[l[k][i]])
{
oldd[l[k][i]]=oldd[k]+cost[k][l[k][i]];
if(!used[l[k][i]])
{
q.push(l[k][i]);
used[l[k][i]]=true;
}
}
}
}
void swap(int i,int j)
{
int aux;
aux=h[i];
h[i]=h[j];
h[j]=aux;
pos[h[i]]=i;
pos[h[j]]=j;
}
void heap_up(int k)
{
if(k<=1) return;
int i=k/2;
if(d[h[k]]<d[h[i]])
{
swap(i,k);
heap_up(i);
}
}
void heap_dw(int k)
{
int i=2*k;
if(i<=nh)
{
if(i+1<=nh && d[h[i+1]]<d[h[i]]) i++;
if(d[h[i]]<d[h[k]])
{
swap(k,i);
heap_dw(i);
}
}
}
int extract()
{
swap(1,nh--);
pos[h[nh+1]]=0;
return h[nh+1];
}
int dijkstra()
{
int k,newcost;
nh=n;
for(int i=1;i<=n;i++) {h[i]=i; pos[i]=i; d[i]=inf; father[i]=0;}
d[source]=reald[source]=0;
swap(1,source);
while(nh>0)
{
k=extract();
heap_dw(1);
for(unsigned int i=0;i<l[k].size();i++)
if(pos[l[k][i]] && f[k][l[k][i]]<c[k][l[k][i]])
{
newcost=d[k]+cost[k][l[k][i]]+oldd[k]-oldd[l[k][i]];
if(newcost<d[l[k][i]])
{
d[l[k][i]]=newcost;
reald[l[k][i]]=reald[k]+cost[k][l[k][i]];
father[l[k][i]]=k;
heap_up(pos[l[k][i]]);
}
}
}
memcpy(oldd,reald,sizeof(reald));
if(d[sink]==inf) return 0;
return 1;
}
void update()
{
int minn=inf;
for(int i=sink;father[i];i=father[i])
minn=min(minn,c[father[i]][i]-f[father[i]][i]);
for(int i=sink;father[i];i=father[i])
{
f[father[i]][i]+=minn;
f[i][father[i]]-=minn;
}
flow+=minn;
flowcost+=minn*reald[sink];
}
int main()
{
freopen("fmcm.in","r",stdin);
freopen("fmcm.out","w",stdout);
read();
bellman();
while(dijkstra()) update();
printf("%d",flowcost);
fclose(stdin);
fclose(stdout);
return 0;
}