Pagini recente » Cod sursa (job #774386) | Cod sursa (job #469532) | Cod sursa (job #2187729) | Cod sursa (job #1159019) | Cod sursa (job #998844)
Cod sursa(job #998844)
#include<fstream>
using namespace std;
typedef struct celula{
int nod;
celula *next;
}*lista;
typedef struct {int nod,dist; } tip;
tip heap[355];
lista graf[355],v;
int i,j,n,m,cap[355][355],cost[355][355],s,d,dist[355],x,y,coada[10000],aux[355][355],tata[355],sol,hp;
bool viz[355];
void upheap(int nod) { if (nod>1&&heap[nod].dist<heap[nod/2].dist) { tip w=heap[nod]; heap[nod]=heap[nod/2]; heap[nod/2]=w; upheap(nod/2); }}
void downheap(int nod) {
if (2*nod<=hp&&heap[2*nod].dist<heap[nod].dist&&(heap[2*nod].dist<heap[2*nod+1].dist||2*nod+1>hp)) { tip w=heap[nod]; heap[nod]=heap[nod*2]; heap[nod*2]=w; downheap(2*nod);}
else if (2*nod<hp&&heap[2*nod+1].dist<heap[nod].dist&&heap[2*nod+1].dist<heap[2*nod].dist) { tip w=heap[nod]; heap[nod]=heap[nod*2+1]; heap[nod*2+1]=w; downheap(2*nod+1);}
}
void sterge(){
heap[1]=heap[hp]; --hp; downheap(1);
}
void baga(int nod, int dist) {
++hp; heap[hp].nod=nod; heap[hp].dist=dist; upheap(hp);
}
bool exista_drum(){
memset(viz,0,sizeof(viz)); dist[s]=0;
viz[s]=s; hp=1; heap[hp].nod=s; heap[hp].dist=0;
while (hp&&viz[d]==0) {
int nod=heap[1].nod; sterge();
for (lista p=graf[nod]; p; p=p->next)
if (viz[p->nod]==0&&cap[nod][p->nod]>0) { dist[p->nod]=dist[nod]+aux[nod][p->nod];
tata[p->nod]=nod; viz[p->nod]=1; baga(p->nod,dist[p->nod]);
}
}
return(viz[d]);
}
int main(void){
ifstream fin("fmcm.in");
ofstream fout("fmcm.out");
fin>>n>>m>>s>>d;
for (i=1; i<=m; ++i) {
fin>>x>>y>>cap[x][y]>>cost[x][y]; cost[y][x]=-cost[x][y];
v=new celula; v->nod=x; v->next=graf[y]; graf[y]=v;
v=new celula; v->nod=y; v->next=graf[x]; graf[x]=v;
}
//aflu distanta minima cu Ford si modific costurile muchiilor astfel incit sa nu am arce de cost negativ
int st=1,en=1; coada[1]=s; viz[s]=1;
for (i=1; i<=n; ++i) dist[i]=1000000000; dist[s]=0;
while (st<=en) {
int nod=coada[st];
for (lista p=graf[nod]; p; p=p->next)
if (dist[p->nod]>dist[nod]+cost[nod][p->nod]&&cap[nod][p->nod]>0) {
dist[p->nod]=dist[nod]+cost[nod][p->nod];
if (viz[p->nod]==0) { ++en; coada[en]=p->nod; }
}
viz[nod]=0; ++st;
}
for (i=1; i<=n; ++i)
for (j=1; j<=n; ++j)
if (cap[i][j]>0) aux[i][j]=cost[i][j]+dist[i]-dist[j];
//caut drumuri de ameliorare de cost minim cu Dijkstra
while (exista_drum()){
int q=d,mmin=1000000000,sum=0;
while (q!=s) { mmin=min(mmin,cap[tata[q]][q]); sum+=cost[tata[q]][q]; q=tata[q]; }
sol+=sum*mmin;
q=d;
while (q!=s) {
cap[tata[q]][q]-=mmin;
cap[q][tata[q]]+=mmin;
aux[tata[q]][q]=cost[tata[q]][q]+dist[tata[q]]-dist[q];
aux[q][tata[q]]=cost[q][tata[q]]+dist[q]-dist[tata[q]];
q=tata[q];
}
}
fout<<sol;
return(0);
}