Cod sursa(job #771551)

Utilizator igsifvevc avb igsi Data 26 iulie 2012 13:05:46
Problema Flux maxim de cost minim Scor 20
Compilator c Status done
Runda Arhiva educationala Marime 2.47 kb
#include <stdio.h>
#include <stdlib.h>
#define inf 2000000000
#define maxn 351
#define maxz 0

struct list{
  int v;
  int c;
  struct list *n;
} *G[maxn];

int H[maxn], posInH[maxn], D[maxn], T[maxn], TC[maxn];
int N, Hsize;
int source, sink, C[maxn][maxn], F[maxn][maxn];

int dijkstra();
void up(int pos);
int pop();

int main()
{
	int m, a, b, c, z;
  struct list *p;
  int i, flow, maxFlow, cost, minCost;
  FILE *in = fopen("fmcm.in", "r");
  FILE *out = fopen("fmcm.out", "w");

  fscanf(in, "%d %d %d %d", &N, &m, &source, &sink);
  for(; m; --m)
  {
    fscanf(in, "%d %d %d %d", &a, &b, &c, &z);
    
    C[a][b] = c;

    p = malloc(sizeof(struct list));
    p->v = b;
    p->c = maxz + z;
    p->n = G[a];
    G[a] = p;

    p = malloc(sizeof(struct list));
    p->v = a;
    p->c = maxz - z;
    p->n = G[b];
    G[b] = p;
  }
  
  maxFlow = minCost = 0;
  while(dijkstra())
  {
  	flow = inf;
  	for(i = sink; i != source && i; i = T[i])
  		if(flow > C[T[i]][i] - F[T[i]][i])
  			flow = C[T[i]][i] - F[T[i]][i];
  	
  	cost = 0;
  	for(i = sink; i != source && i; i = T[i])
  	{
  		F[T[i]][i] += flow;
  		F[i][T[i]] -= flow;
  		cost += flow * TC[i];
  	}
  	minCost += cost;
  	maxFlow += flow;
  }
  
  fprintf(out, "%d\n", minCost);
	fclose(out);
  fclose(in);
	return 0;
}

int dijkstra()
{
  int min, i;
  struct list *p;

  for(i = 1; i <= N; ++i)
    T[i] = 0,
    D[i] = inf,
    H[i] = posInH[i] = i;

  Hsize = N;
  D[source] = 0;
  H[1] = source;
  H[source] = 1;
  posInH[source] = 1;
  posInH[1] = source;

  while(Hsize)
  {
    min = pop();
    if(min == inf) break;
    
    for(p = G[min]; p; p = p->n)
      if(C[min][p->v] > F[min][p->v] && D[p->v] > D[min] + p->c)
      {
        D[p->v] = D[min] + p->c;
        T[p->v] = min;
        TC[p->v] = p->c - maxz;
        up( posInH[p->v] );
      }
  }

  return T[sink];
}

int pop()
{
  int v, pos, next, aux;

  v = H[1];
  H[1] = H[ Hsize-- ];
  posInH[ H[1] ] = 1;

  for(pos = next = 1; 1; pos = next)
  {
    if(pos<<1 <= Hsize && H[next] > H[pos<<1])
      next <<= 1;
    if((pos<<1)+1 <= Hsize && H[next] > H[(pos<<1)+1])
      next = (pos<<1)+1;

    if(next == pos) break;

    aux = H[pos]; H[pos] = H[next]; H[next] = aux;
    posInH[ H[pos] ] = pos;
    posInH[ H[next] ] = next;
  }

  return v;
}


void up(int pos)
{
  int aux, next;
  for(next = pos>>1; pos > 1 && H[pos] > H[next]; pos = next, next >>= 1)
  {
    aux = H[pos]; H[pos] = H[next]; H[next] = aux;
    posInH[ H[pos] ] = pos;
    posInH[ H[next] ] = next;
  }
}