Cod sursa(job #303527)

Utilizator drag0shSandulescu Dragos drag0sh Data 9 aprilie 2009 22:21:15
Problema Flux maxim de cost minim Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.67 kb
#include <stdio.h>
#include <vector>

//using namespace std;

#include <algorithm>
#include <vector>
#include <queue>
#include <bitset>

using namespace std;





#define nume "fmcm"
#define N 355
#define M 12005
#define oo 200000000


FILE *in=fopen(nume".in","r"),*out=fopen(nume".out","w");

short int n,m,source,dest,cap[N][N],cost[N][N],path[N],g[N],t[N];
int d[N],costflux,flux;
vector <short int> a[N];

void citire(){
  short int x,y,c,z,i;
  fscanf(in,"%hd%hd%hd%hd",&n,&m,&source,&dest);
  for(i=0;i<m;i++){
    fscanf(in,"%hd %hd %hd %hd",&x,&y,&c,&z);
    a[x].push_back(y);
    a[y].push_back(x);
    cap[x][y]=c;
    cost[x][y]=z;
    cost[y][x]=-z;
  }
  for(i=1;i<=n;i++)g[i]=a[i].size();
  
  
}

void bellman(){
  queue <int>q; bitset <N>v; int nod,fiu,i;
  for(i=1;i<=n;i++)d[i]=oo;
  d[source]=0;
  q.push(source);
  v[source]=1;
  while(!q.empty()){
    nod=q.front();
    q.pop();
    v[nod]=0;
    for(int i=0;i<g[nod];i++){
      fiu=a[nod][i];
      if(cap[nod][fiu]){
	if(d[fiu]>d[nod]+cost[nod][fiu]){
	  d[fiu]=d[nod]+cost[nod][fiu];
	  t[fiu]=nod;
	  if(!v[fiu]){v[fiu]=1;q.push(fiu);}
	}
      }
    }
      
  }
}


void calculare_flux(){
  int aux,minim,i;
   do{
    bellman();
    if(d[dest]==oo)break;
    for(aux=dest,m=0;aux;path[++m]=aux,aux=t[aux]);
    minim=oo;
    for(i=1;i<m;++i)
      if(cap[path[i+1]][path[i]]<minim)minim=cap[path[i+1]][path[i]];//invers take care
    for(i=1;i<m;++i){
      cap[path[i+1]][path[i]]-=minim;
      cap[path[i]][path[i+1]]+=minim;
    }
    flux+=minim;
    costflux+=minim*d[dest];
   
   }
   while (1);
}

int main(){
  citire();
   calculare_flux();
  fprintf(out,"%d",costflux);
  
  
  fclose(in);
  fclose(out);
  return 0;
}