Pagini recente » Cod sursa (job #1936956) | Cod sursa (job #1314057) | Cod sursa (job #1628821) | Cod sursa (job #2764709) | Cod sursa (job #298357)
Cod sursa(job #298357)
//dijkstra cu heapuri
#include <fstream>
#define lg_max 355
#define infinit 1<<30
using namespace std;
ifstream fin("fmcm.in");
ofstream fout("fmcm.out");
struct nod
{
int inf,cost;
nod *next;
} *sir[lg_max];
int heap[lg_max],dist[lg_max],viz[lg_max],C[lg_max][lg_max];
int n,m,nr,tati[lg_max],S,D,rez;
void adauga(int a,int b,int c)
{
nod *q=new nod;
q->inf=a;
q->cost=c;
q->next=sir[b];
sir[b]=q;
}
void citire()
{
fin>>n>>m>>S>>D;
int a,b,cost,flux;
for (int i=0;i<m;i++)
{
fin>>a>>b>>flux>>cost;
cost+=1001;
adauga(b,a,cost);
adauga(a,b,-cost);
C[a][b]=flux;
}
}
void initializare()
{
for (int i=1;i<=n;i++)
{
heap[i]=i;
dist[i]=infinit;
viz[i]=-1;
}
nr++;
dist[S]=0;
heap[1]=S;
viz[S]=1;
}
void schimba(int a,int b)
{
int aux=heap[a];
heap[a]=heap[b];
heap[b]=aux;
}
void in_jos(int poz)
{
while (poz<=nr)
{
int c=poz;
if ((poz<<1)>nr)
return;
c=poz<<1;
if ( c+1<=nr)
if ( dist[heap[c+1]] < dist[heap[c]])
c++;
if (dist[heap[poz]]<= dist[heap[c]])
return;
viz[heap[poz]]=c;
viz[heap[c]]=poz;
schimba(poz,c);
poz=c;
}
}
void in_sus(int poz)
{
while (poz>1)
{
if (dist[heap[poz]]<dist[heap[poz>>1]])
{
viz[heap[poz]]=poz>>1;
viz[heap[poz>>1]]=poz;
schimba(poz,poz>>1);
poz=poz>>1;
}
else
return ;
}
}
void dijkstra()
{
int min;
initializare();
nr=1;
while (nr)
{
min=heap[1];
schimba(1,nr);
viz[heap[1]]=1;
nr--;
in_jos(1);
for (nod *i=sir[min];i;i=i->next)
if (C[min][i->inf]&& dist[i->inf]>dist[min]+i->cost)
{
dist[i->inf]=dist[min]+i->cost;
tati[i->inf]=min;
if (viz[i->inf]==-1)
{
nr++;
heap[nr]=i->inf;
viz[heap[nr]]=nr;
in_sus(nr);
}
else
in_sus(viz[i->inf]);
}
}
}
int mini(int a,int b)
{
return a>b?b:a;
}
void bell()
{
int flux,poz;
dijkstra();
while (dist[D]!=infinit)
{
flux=infinit;
poz=D;
while (poz!=S)
{
flux=mini(flux,C[tati[poz]][poz]);
poz=tati[poz];
}
poz=D;
int num=0;
while (poz!=S)
{
C[tati[poz]][poz]-=flux;
C[poz][tati[poz]]+=flux;
poz=tati[poz];
num++;
}
rez+=flux*(dist[D]-num*1001);
dijkstra();
}
}
int main ()
{
citire();
bell();
fout<<rez;
return 0;
}