Cod sursa(job #771594)

Utilizator igsifvevc avb igsi Data 26 iulie 2012 15:11:37
Problema Flux maxim de cost minim Scor 50
Compilator c Status done
Runda Arhiva educationala Marime 1.76 kb
#include <stdio.h>
#include <stdlib.h>
#define inf 2000000000
#define maxn 351

struct list { int v; struct list *n; } *G[maxn];
int C[maxn][maxn], F[maxn][maxn], Z[maxn][maxn];
int Q[2][maxn], D[maxn], T[maxn], inQ[maxn];
int N, source, sink;

int bellmanford();

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

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

int bellmanford()
{
	int choose, i, j, ok, v;
	struct list *p;
	
	for(i = 1; i <= N; ++i)
		T[i] = inQ[i] = 0,
		D[i] = inf;
	
	D[source] = 0;
	Q[0][0] = 1;
	Q[0][1] = source;
	choose = 0;
	
	for(i = ok = 1; i < N && ok; ++i)
	{
		Q[1-choose][0] = 0;
		for(ok = 0, j = 1; j <= Q[choose][0]; ++j)
		{
			v = Q[choose][j];
			for(p = G[v]; p; p = p->n)
				if(C[v][p->v] > F[v][p->v] && D[p->v] > D[v] + Z[v][p->v])
				{
					ok = 1;
					D[p->v] = D[v] + Z[v][p->v];
					T[p->v] = v;
					if(inQ[p->v] != i)
					{
						Q[1-choose][++Q[1-choose][0]] = p->v;
						inQ[p->v] = i;
					}
				}
		}
		choose = 1 - choose;
	}
	
	return T[sink];
}