Pagini recente » Cod sursa (job #1926547) | Cod sursa (job #1242503) | Cod sursa (job #244858) | Cod sursa (job #1921372) | Cod sursa (job #304020)
Cod sursa(job #304020)
#include <fstream>
#include <queue>
#include <vector>
#include <bitset>
using namespace std;
const int NMAX=351;
const int Inf=2000000000;
int N,M,r[NMAX][NMAX],c[NMAX][NMAX],source,sink;
vector<int> G[NMAX];
ifstream f("fmcm.in");
ofstream g("fmcm.out");
bool ok=true;
int mincost,aux;
int d[NMAX],t[NMAX];
bitset<NMAX> u;
queue<int> Q;
void Bellman_Ford(){
for (int i=1;i<=N;++i) d[i]=Inf;
Q.push(source);
u[source]=1;
d[source]=0;
while (!Q.empty()){
int x=Q.front();
Q.pop();
u[x]=0;
for (vector<int>::iterator it=G[x].begin();it!=G[x].end();++it)
if (r[x][*it]>0)
if (d[*it]>d[x]+c[x][*it]){
d[*it]=d[x]+c[x][*it];
if (!u[*it]) Q.push(*it),u[*it]=1;
}
}
aux=d[sink];
}
int h[NMAX],p[NMAX],nrH;
void Sift(int k){
int Son;
if (2*k<=nrH){
Son=2*k;
if (Son+1<=nrH && d[h[Son+1]]<d[h[Son]]) ++Son;
if (d[h[Son]]>=d[h[k]]) Son=0;
}else Son=0;
while (Son){
p[h[k]]=Son;p[h[Son]]=k;
int w=h[k];h[k]=h[Son];h[Son]=w;
k=Son;
if (2*k<=nrH){
Son=2*k;
if (Son+1<=nrH && d[h[Son+1]]<d[h[Son]]) ++Son;
if (d[h[Son]]>=d[h[k]]) Son=0;
}else Son=0;
}
}
void Percolate(int k){
if (k>nrH) return;
int key=h[k];
while (k>1 && d[key]<d[h[k/2]]){
p[h[k/2]]=k;
h[k]=h[k/2];
k/=2;}
h[k]=key;
p[key]=k;
}
void add(int i){
h[++nrH]=i;
p[i]=nrH;
Percolate(nrH);
}
int Extract_Min(){
int x=h[1];
p[x]=nrH;
h[1]=h[nrH--];
p[h[1]]=1;
Sift(1);
return x;
}
void drum(){
vector<int>::iterator it;
int x;
ok=false;
mincost=0;
for (x=1;x<=N;++x)
for (it=G[x].begin();it!=G[x].end();++it)
if (d[x]<Inf && d[*it]<Inf)
c[x][*it]+=d[x]-d[*it];
for (x=1;x<=N;++x) d[x]=Inf,t[x]=0;
d[source]=0;t[source]=source;
for (x=1;x<=N;++x) add(x);
while (nrH>0){
x=Extract_Min();
for (it=G[x].begin();it!=G[x].end();++it)
if (r[x][*it]>0)
if (d[*it]>d[x]+c[x][*it]){
d[*it]=d[x]+c[x][*it];
Percolate(p[*it]);
t[*it]=x;}
}
if (!t[sink]) return;
ok=true;
int rmin=Inf;
for (x=sink;t[x]!=x;x=t[x])
rmin=min(rmin,r[t[x]][x]);
for (x=sink;t[x]!=x;x=t[x])
r[t[x]][x]-=rmin,
r[x][t[x]]+=rmin;
aux+=d[sink];
mincost=aux*rmin;
}
int solve(){
int sol=0;
while (ok){
drum();
sol+=mincost;
}
return sol;
}
int main(){
int i,j,cap,cost;
f>>N>>M>>source>>sink;
while (M--){
f>>i>>j>>cap>>cost;
G[i].push_back(j);
G[j].push_back(i);
r[i][j]=cap;
c[i][j]=cost;
c[j][i]=-cost;
}
Bellman_Ford();
g<<solve();
return 0;
}