Cod sursa(job #304018)

Utilizator mihai_floreaFlorea Mihai Alexandru mihai_florea Data 10 aprilie 2009 18:34:40
Problema Flux maxim de cost minim Scor 70
Compilator cpp Status done
Runda Arhiva educationala Marime 1.83 kb
#include <cstdio>
#include <vector>
#include <queue>
using namespace std;
#define pb push_back
const int NMAX=353;
vector<int> G[NMAX];
int N,M,Source,Sink,cst[NMAX][NMAX],f[NMAX][NMAX],cap[NMAX][NMAX];
void read(){
     freopen("fmcm.in","r",stdin);
     freopen("fmcm.out","w",stdout);
     scanf("%d %d %d %d",&N,&M,&Source,&Sink);
     int x,y,capacitate,cost;
     while (M--){
          scanf("%d %d %d %d",&x,&y,&capacitate,&cost);
          G[x].pb(y);
          G[y].pb(x);
          cap[x][y]=capacitate;
          cst[x][y]=cost;
          cst[y][x]=-cost;
          }
     }
queue<int> Q;
bool gasit,U[NMAX];;
int dmin,sol,t[NMAX],d[NMAX];
void drum(){
     vector<int>::iterator it;
     int i;
     memset(U,false,sizeof(U));
     memset(d,0x3f,sizeof(d));
     memset(t,0,sizeof(t));
     U[Source]=true;
     d[Source]=0;
     t[Source]=Source;
     dmin=0;gasit=false;
     
     for (Q.push(Source);!Q.empty();Q.pop()){
         i=Q.front();
         U[i]=false;
         for (it=G[i].begin();it!=G[i].end();++it)
           if (f[i][*it]<cap[i][*it])
            if (d[*it]>d[i]+cst[i][*it]){
              d[*it]=d[i]+cst[i][*it];
              t[*it]=i;
              if (!U[*it]) Q.push(*it),U[*it]=true;
              } 
         }
              
     if (!t[Sink]) return;
     gasit=true;
     
     int fmin=2000000000;
     for (i=Sink;i!=Source;i=t[i])
       fmin=min(fmin,cap[t[i]][i]-f[t[i]][i]);
     for (i=Sink;i!=Source;i=t[i])
       f[t[i]][i]+=fmin,
       f[i][t[i]]-=fmin;
       
     dmin=fmin*d[Sink];
     }   
              
void solve(){
     int sol=0;
     gasit=true;
     while (gasit){
        drum(); 
        sol+=dmin;
        }
     freopen("fmcm.out","w",stdout);
     printf("%d",sol);
     }
int main(){
    read();
    solve();
    return 0;
}