Cod sursa(job #304020)

Utilizator mihai_floreaFlorea Mihai Alexandru mihai_florea Data 10 aprilie 2009 18:36:22
Problema Flux maxim de cost minim Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 3.02 kb
#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;
}