Cod sursa(job #2908833)

Utilizator iraresmihaiiordache rares mihai iraresmihai Data 6 iunie 2022 08:37:23
Problema Flux maxim Scor 70
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 3 kb
#include <iostream>
#include <vector>
#include <queue>

#define MAXN 1000
#define MAXM 3000
using namespace std;

struct edge{
  int b, direction, indForEdgeCalc;
};

struct edgeCalc{
  int maxFlux, usedFlux;
};

struct node{
  int lvl;
  int totFlux;
  vector <edge> edges;
};

node graph[MAXN];
edgeCalc edges[MAXM];
bool isInOp[MAXN];
int sizeEdgeCalc;
queue <int> op;

void addEdge(int a, int b, int maxFlux) {
  graph[a].edges.push_back({b, 1, sizeEdgeCalc});
  graph[b].edges.push_back({a, -1, sizeEdgeCalc});
  edges[sizeEdgeCalc].maxFlux = maxFlux;
  sizeEdgeCalc++;
}

int findMinLvl(int pos) {
  int ans;
  ans = MAXN + 1;

  for ( edge i : graph[pos].edges ) {
    if ( graph[i.b].lvl < ans && ((i.direction == 1 && edges[i.indForEdgeCalc].usedFlux < edges[i.indForEdgeCalc].maxFlux) || (i.direction == -1 && edges[i.indForEdgeCalc].usedFlux)) )
      ans = graph[i.b].lvl;
  }

  return ans;
}

void initialise(int n) {
  graph[0].lvl = n;
  for ( edge i : graph[0].edges ) {
    edges[i.indForEdgeCalc].usedFlux = edges[i.indForEdgeCalc].maxFlux;
    graph[i.b].totFlux += edges[i.indForEdgeCalc].maxFlux;
    if ( i.b != n - 1 ) {
      op.push(i.b);
      isInOp[i.b] = true;
    }
  }
}

void pushVol(int pos, int n, int x) {
  int toAdd, startFlux;

  for ( edge i : graph[pos].edges ) {
    if ( graph[i.b].lvl < graph[pos].lvl ) {
      startFlux = graph[i.b].totFlux;
      if ( i.direction > 0 && edges[i.indForEdgeCalc].maxFlux > edges[i.indForEdgeCalc].usedFlux ) {
        toAdd = min(graph[pos].totFlux, edges[i.indForEdgeCalc].maxFlux - edges[i.indForEdgeCalc].usedFlux);
        edges[i.indForEdgeCalc].usedFlux += toAdd;
        graph[i.b].totFlux += toAdd;
        graph[pos].totFlux -= toAdd;
      } else if ( i.direction < 0 && edges[i.indForEdgeCalc].usedFlux ) {
        toAdd = min(graph[pos].totFlux, edges[i.indForEdgeCalc].usedFlux);
        edges[i.indForEdgeCalc].usedFlux -= toAdd;
        if ( i.b )
          graph[i.b].totFlux += toAdd;
        graph[pos].totFlux -= toAdd;
      }
      if ( startFlux == 0 && graph[i.b].totFlux > 0 && i.b && i.b != n - 1 && !isInOp[i.b] ) {
        op.push(i.b);
        isInOp[i.b] = true;
      }
    }
    if ( !graph[pos].totFlux )
      break;
  }
}

void calcAns(int n) {
  int pos, x;

  initialise(n);

  x = 0;
  while ( op.size() ) {
    pos = op.front();
    op.pop();
    isInOp[pos] = false;
    pushVol(pos, n, x); ///nu uita de x
    if ( graph[pos].totFlux ) {
      graph[pos].lvl = findMinLvl(pos) + 1;
      op.push(pos);
    }
    x++;
  }
}

int main() {
  FILE *fin, *fout;
  fin = fopen("maxflow.in", "r");
  fout = fopen("maxflow.out", "w");

  int n, m, i, a, b, flux;

  fscanf(fin, "%d%d", &n, &m);

  for ( i = 0; i < m; i++ ) {
    fscanf(fin, "%d%d%d", &a, &b, &flux);
    a--;
    b--;

    addEdge(a, b, flux);
  }

  calcAns(n);

  fprintf(fout, "%d\n", graph[n - 1].totFlux);

  fclose(fin);
  fclose(fout);

  return 0;
}