Pagini recente » Cod sursa (job #357772) | Cod sursa (job #2154679) | Cod sursa (job #2788981) | Cod sursa (job #1751524) | Cod sursa (job #934944)
Cod sursa(job #934944)
#include <fstream>
#include <queue>
#include <vector>
#define nmax 356
#define oo (1<<30)
#define Vecin first
#define Cost second
using namespace std;
vector < pair<int,int> > G[nmax];
queue <int> Q;
int N,Start,sw=1,Destination,nrinQ[nmax];
int maxflow,Sum,T[nmax],Flux[nmax][nmax];
bool inQ[nmax];
class HEAP {
#define NMAxHeap nmax
#define left(i) (2*i)
#define right(i) (2*i+1)
#define father(i) (i/2)
#define cmp(a,b) (Dist[V[a]]<Dist[V[b]])
private:
int V[NMAxHeap],Loc[NMAxHeap],Vf;
public:
int Dist[NMAxHeap];
public:
HEAP():Vf(0){}
void push(int,int);
void pop();
void update(int,int);
int top();
int size();
private:
void Up(int);
void Down(int);
};
void HEAP::Up(int nod) {
while(nod>1&&cmp(nod,father(nod))) {
swap(V[nod],V[father(nod)]);
swap(Loc[V[nod]],Loc[V[father(nod)]]);
nod=father(nod);
}
}
void HEAP::Down(int nod) {
int son;
do {
son=0;
if(left(nod)<=Vf) {
son=left(nod);
if(right(nod)<=Vf&&cmp(right(nod),son))
son=right(nod);
if(cmp(nod,son))
son=0;
}
if(son) {
swap(V[nod],V[son]);
swap(Loc[V[nod]],Loc[V[son]]);
nod=son;
}
}while(son);
}
void HEAP::push(int id,int Val) {
V[++Vf]=id;
Dist[id]=Val;
Loc[id]=Vf;
this->Up(Vf);
}
void HEAP::pop() {
V[1]=V[Vf--];
Loc[V[1]]=1;
this->Down(1);
}
void HEAP::update(int id,int Val) {
Dist[id]=Val;
this->Up(Loc[id]);
this->Down(Loc[id]);
}
int HEAP::top() {
return V[1];
}
int HEAP::size() {
return Vf;
}
HEAP Heap;
bool Dijkstra() {
int i,j,Nod;
if(sw) {
sw=0;
for(i=1;i<=N;i++)
for(j=0;j<G[i].size();j++)
if(Heap.Dist[i]!=oo && Heap.Dist[G[i][j].Vecin]!=oo)
G[i][j].Cost+=Heap.Dist[i]-Heap.Dist[G[i][j].Vecin];
}
Heap.push(Start,0);
for(i=1;i<=N;i++)
if(i!=Start)
Heap.push(i,oo);
while(Heap.size()) {
Nod=Heap.top();
Heap.pop();
for(i=0;i<G[Nod].size();i++)
if(Flux[Nod][G[Nod][i].Vecin]>0 && Heap.Dist[Nod] + G[Nod][i].Cost < Heap.Dist[G[Nod][i].Vecin] ) {
T[G[Nod][i].Vecin]=Nod;
Heap.update(G[Nod][i].Vecin, Heap.Dist[Nod] + G[Nod][i].Cost);
}
}
return (Heap.Dist[Destination]!=oo);
}
void BellmanFord(int Start) {
int i,Nod;
for(i=1;i<=N;i++)
Heap.Dist[i]=oo;
Q.push(Start);
Heap.Dist[Start]=0;
while(!Q.empty()) {
Nod=Q.front();
inQ[Nod]=0;
Q.pop();
for(i=0;i<G[Nod].size();i++)
if(Flux[Nod][G[Nod][i].Vecin]>0 && Heap.Dist[Nod]+G[Nod][i].Cost<Heap.Dist[G[Nod][i].Vecin]) {
Heap.Dist[G[Nod][i].Vecin]=Heap.Dist[Nod]+G[Nod][i].Cost;
if(!inQ[G[Nod][i].Vecin]) {
Q.push(G[Nod][i].Vecin);
inQ[G[Nod][i].Vecin]=1;
nrinQ[G[Nod][i].Vecin]++;
if(nrinQ[G[Nod][i].Vecin]>=N)
return;
}
}
}
Sum=Heap.Dist[Destination];
}
void Solve() {
int flux,e,nod;
BellmanFord(Start);
while(Dijkstra()) {
flux=oo;
e=0;
for(nod=Destination;nod!=Start;nod=T[nod],e++)
flux=min(flux,Flux[T[nod]][nod]);
for(nod=Destination;nod!=Start;nod=T[nod]) {
Flux[T[nod]][nod]-=flux;
Flux[nod][T[nod]]+=flux;
}
Sum+=Heap.Dist[Destination];
maxflow+=flux*Sum;
}
}
void Read() {
int x,y,f,c,M;
ifstream in("fmcm.in");
in>>N>>M>>Start>>Destination;
while(M--) {
in>>x>>y>>f>>c;
Flux[x][y]=f;
G[x].push_back(make_pair(y,c));
G[y].push_back(make_pair(x,-c));
}
in.close();
}
void Write() {
ofstream out("fmcm.out");
out<<maxflow<<'\n';
out.close();
}
int main() {
Read();
Solve();
Write();
}