Cod sursa(job #3228260)

Utilizator iraresmihaiiordache rares mihai iraresmihai Data 7 mai 2024 10:15:56
Problema Flux maxim Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.7 kb
#include <iostream>
#include <queue>

#define MAXN 1010
#define MAX_EDGES 10010
#define INF 1000000000
#define MAX_POW 65536
using namespace std;

struct edge{
  int to, id;
};

struct node{
  bool vis;
  int lvl;
  int currEdge;
  vector <edge> neighbours;
};

node graph[MAXN];
long long edges[MAX_EDGES];
long long accCap[MAX_EDGES];
int edgesSize;
queue <int> toVisit;
int source, sink, nrNodes;
long long flux;
int p;

void addEdge(int a, int b, long long cap) {
  graph[a].neighbours.push_back({b, edgesSize});
  graph[b].neighbours.push_back({a, edgesSize + 1});
  edges[edgesSize] = cap;
  edges[edgesSize + 1] = 0;
  accCap[edgesSize] = accCap[edgesSize + 1] = cap;
  edgesSize += 2;
}

bool bfs() {
  int i, pos;

  for ( i = 0; i < nrNodes; i++ ) {
    graph[i].lvl = -1;
  }

  graph[source].lvl = 0;
  toVisit.push(source);
  while ( toVisit.size() && graph[sink].lvl == -1 ) {
    pos = toVisit.front();
    toVisit.pop();

    for ( edge x : graph[pos].neighbours ) {
      if ( graph[x.to].lvl == -1 && edges[x.id] && accCap[x.id] >= p ) {
        graph[x.to].lvl = graph[pos].lvl + 1;
        toVisit.push(x.to);
      }
    }
  }
  while ( toVisit.size() ) {
    toVisit.pop();
  }

  return (graph[sink].lvl != -1);
}

void resetForDfs() {
  int i;

  for ( i = 0; i < nrNodes; i++ ) {
    graph[i].currEdge = 0;
  }
}

long long dfs(int pos, long long currF) {
  if ( pos == sink ) {
    return currF;
  }

  int i, to, id;
  long long someF;

  while ( graph[pos].currEdge < graph[pos].neighbours.size() ) {
    i = graph[pos].currEdge;
    to = graph[pos].neighbours[i].to;
    id = graph[pos].neighbours[i].id;

    if ( edges[id] && graph[to].lvl == graph[pos].lvl + 1 && accCap[id] >= p ) {
      someF = min(currF, edges[id]);
      someF = dfs(to, someF);

      if ( someF ) {
        edges[id] -= someF;
        edges[id ^ 1] += someF;
        return someF;
      }
    }
    graph[pos].currEdge++;
  }

  return 0;
}

void makeFlux() {
  while ( bfs() ) {
    resetForDfs();
    while ( graph[source].currEdge < graph[source].neighbours.size() ) {
      flux += dfs(source, INF);
    }
  }
}

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

  int m, i, a, b;
  long long cap;

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

  source = 1;
  sink = nrNodes;
  nrNodes++;

  edgesSize = 2;
  for ( i = 0; i < m; i++ ) {
    fscanf(fin, "%d%d%lld", &a, &b, &cap);

    addEdge(a, b, cap);
  }

  flux = 0;
  p = MAX_POW;
  while ( p ) {
    makeFlux();
    p /= 2;
  }

  fprintf(fout, "%lld\n", flux);

  fclose(fin);
  fclose(fout);

  return 0;
}