Cod sursa(job #333451)

Utilizator mlazariLazari Mihai mlazari Data 22 iulie 2009 20:37:02
Problema Flux maxim de cost minim Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 2.74 kb
#include<stdio.h>

#define NMAX 353
#define INF 2000000003
#define minim(a,b) (a)<(b)?(a):(b);

struct heap {
  int l;
  int w[NMAX],p[NMAX];
};

heap h;
long long rez=0;
int n,m,s,d,drum=1,sum;
int dist[NMAX],t[NMAX],g[NMAX];
int v[NMAX][NMAX],cap[NMAX][NMAX],cost[NMAX][NMAX],flux[NMAX][NMAX];

void add(int x,int y) {
  v[x][++g[x]]=y;
}

void swap(int &a,int &b) {
  int c=a;
  a=b;
  b=c;
}

void upheap(int x) {
  while((x>1)&&(dist[h.w[x]]<dist[h.w[x>>1]])) {
    swap(h.w[x],h.w[x>>1]);
    swap(h.p[h.w[x]],h.p[h.w[x>>1]]);
    x=x>>1;
  }
}

void downheap(int x) {
  int f;
  while(2*x<=h.l) {
    f=x;
    if(dist[h.w[2*x]]<dist[h.w[f]]) f=2*x;
    if((2*x<h.l)&&(dist[h.w[2*x+1]]<dist[h.w[f]])) f=2*x+1;
    if(f==x) x=h.l;
    else {
      swap(h.w[x],h.w[f]);
      swap(h.p[h.w[x]],h.p[h.w[f]]);
      x=f;
    }
  }
}

int minheap() {
  int min=h.w[1];
  h.w[1]=h.w[h.l];
  h.l--;
  downheap(1);
  return min;
}

void addheap(int x) {
  h.w[++h.l]=x;
  h.p[x]=h.l;
  upheap(h.l);
}

void citeste() {
  int x,y,c,z;
  freopen("fmcm.in","r",stdin);
  scanf("%d %d %d %d",&n,&m,&s,&d);
  for(int i=0;i<m;i++) {
    scanf("%d %d %d %d",&x,&y,&c,&z);
    v[x][++g[x]]=y;
    v[y][++g[y]]=x;
    cap[x][y]=c;
    cost[x][y]=z;
    cost[y][x]=-z;
  }
}

void BellmanFord() {
  int i,j,k;
  for(i=1;i<=n;i++) dist[i]=INF;
  dist[s]=0;
  for(i=1;i<=n-1;i++) {
    for(j=1;j<=n;j++)
     for(k=1;k<=g[j];k++) {
       if((cap[j][v[j][k]]>0)&&(dist[j]+cost[j][v[j][k]]<dist[v[j][k]]))
        dist[v[j][k]]=dist[j]+cost[j][v[j][k]];
     }
  }
  sum=dist[d];
}

int Dijkstra() {
  int i,j,min;
  for(i=1;i<=n;i++)
   for(j=1;j<=g[i];j++)
    if((dist[i]!=INF)&&(dist[v[i][j]]!=INF)) cost[i][v[i][j]]+=dist[i]-dist[v[i][j]];
  for(i=1;i<=n;i++) {
    dist[i]=INF;
    h.w[i]=i;
    h.p[i]=i;
    t[i]=-1;
  }
  dist[s]=0;
  h.w[1]=s; h.w[s]=1;
  h.p[1]=s; h.p[s]=1;
  h.l=n;
  while((h.l>=1)&&(dist[h.w[1]]!=INF)) {
    min=minheap();
    for(i=1;i<=g[min];i++)
     if((cap[min][v[min][i]]>flux[min][v[min][i]])&&(dist[min]+cost[min][v[min][i]]<dist[v[min][i]])) {
       dist[v[min][i]]=dist[min]+cost[min][v[min][i]];
       t[v[min][i]]=min;
       upheap(h.p[v[min][i]]);
     }
  }
  if(dist[d]!=INF) {
    int vmin=INF;
    drum=1;
    for(i=d;i!=s;i=t[i])
     vmin=minim(vmin,cap[t[i]][i]-flux[t[i]][i]);
    for(i=d;i!=s;i=t[i]) {
      flux[t[i]][i]+=vmin;
      flux[i][t[i]]-=vmin;
    }
    sum+=dist[d];
    return vmin*sum;
  }
  return 0;
}

void scrie() {
  freopen("fmcm.out","w",stdout);
  printf("%lld",rez);
}

int main() {
  citeste();
  BellmanFord();
  while(drum) {
    drum=0;
    rez+=Dijkstra();
  }
  scrie();
  return 0;
}