Cod sursa(job #1441643)

Utilizator juniorOvidiu Rosca junior Data 24 mai 2015 11:42:47
Problema Flux maxim Scor 10
Compilator cpp Status done
Runda Arhiva educationala Marime 3.33 kb
#include <stdlib.h>
#include <stdio.h>
#include <fstream>

#define MIN(X,Y) ((X) < (Y) ? (X) : (Y))
#define INFINITE 10000000

using namespace std;

ifstream fin ("maxflow.in");
ofstream fout("maxflow.out");
int nodes, m, i, v1, v2, aux;

void push(const int * const * C, int ** F, int *excess, int u, int v) {
  int send = MIN(excess[u], C[u][v] - F[u][v]);
  F[u][v] += send;
  F[v][u] -= send;
  excess[u] -= send;
  excess[v] += send;
}

void relabel(const int * const * C, const int * const * F, int *height, int u) {
  int v;
  int min_height = INFINITE;
  for (v = 0; v < nodes; v++) {
    if (C[u][v] - F[u][v] > 0) {
      min_height = MIN(min_height, height[v]);
      height[u] = min_height + 1;
    }
  }
};

void discharge(const int * const * C, int ** F, int *excess, int *height, int *seen, int u) {
  while (excess[u] > 0) {
    if (seen[u] < nodes) {
      int v = seen[u];
      if ((C[u][v] - F[u][v] > 0) && (height[u] > height[v])) {
        push(C, F, excess, u, v);
      }
      else
        seen[u] += 1;
    }
    else {
      relabel(C, F, height, u);
      seen[u] = 0;
    }
  }
}

void moveToFront(int i, int *A) {
  int temp = A[i];
  int n;
  for (n = i; n > 0; n--) {
    A[n] = A[n - 1];
  }
  A[0] = temp;
}

int pushRelabel(const int * const * C, int ** F, int source, int sink) {
  int *excess, *height, *list, *seen, i, p;
  excess = (int *) calloc(nodes, sizeof(int));
  height = (int *) calloc(nodes, sizeof(int));
  seen = (int *) calloc(nodes, sizeof(int));
  list = (int *) calloc((nodes - 2), sizeof(int));
  for (i = 0, p = 0; i < nodes; i++) {
    if((i != source) && (i != sink)) {
      list[p] = i;
      p++;
    }
  }
  height[source] = nodes;
  excess[source] = INFINITE;
  for (i = 0; i < nodes; i++)
    push(C, F, excess, source, i);
  p = 0;
  while (p < nodes - 2) {
    int u = list[p];
    int old_height = height[u];
    discharge(C, F, excess, height, seen, u);
    if (height[u] > old_height) {
      moveToFront(p, list);
      p = 0;
    }
    else
      p += 1;
  }
  int maxflow = 0;
  for (i = 0; i < nodes; i++)
    maxflow += F[source][i];
  free(list);
  free(seen);
  free(height);
  free(excess);
  return maxflow;
}

void printMatrix(const int * const * M) {
  int i, j;
  for (i = 0; i < nodes; i++) {
    for (j = 0; j < nodes; j++)
      printf("%d\t", M[i][j]);
    printf("\n");
  }
}

int main(void) {
  fin >> nodes >> m;
  int **flow, **capacities, i;
  flow = (int **) calloc(nodes, sizeof(int*));
  capacities = (int **) calloc(nodes, sizeof(int*));
  for (i = 0; i < nodes; i++) {
    flow[i] = (int *) calloc(nodes, sizeof(int));
    capacities[i] = (int *) calloc(nodes, sizeof(int));
  }
	for (i = 1; i <= m; i++) {
		fin >> v1 >> v2 >> aux; // capacitatile arcelor [! trebuie aux ! altfel nu citeste bine datorita alocarii cu huge]
		capacities[v1 - 1][v2 - 1] = aux;
	}
  //Sample graph
  capacities[0][1] = 3;
  capacities[0][2] = 5;
  capacities[1][3] = 6;
  capacities[2][3] = 4;
  capacities[2][1] = 3;
  /*
  capacities[2][4] = 7;
  capacities[3][5] = 7;
  capacities[4][5] = 4;
  printf("Capacity:\n");
  printMatrix(capacities);*/
  fout << pushRelabel(capacities, flow, 0, nodes - 1);
  //printf("Max Flow:\n%d\n", ;
  /*printf("Flows:\n");
  printMatrix(flow);*/
  return 0;
}