Cod sursă (job #308601)

Utilizator avatar Men_in_Black Marco Polo Men_in_Black IP ascuns
Problemă Push-Relabel (clasele 11-12) Compilator cpp | 2.05 kb
Rundă Arhiva de probleme Status evaluat
Dată 12 iul. 2017 17:35:37 Scor 50
#include <algorithm>
#include <iostream>
#include <fstream>
#include <climits>
#include <vector>
#include <queue>

using namespace std;

ifstream in("push-relabel.in");
ofstream out("push-relabel.out");

const int NMAX = 800;

struct Edge{
  int to;
  int rev;
  int flow;
  int cap;
};

int n, src, dest;
int cap[1 + NMAX][1 + NMAX];
int rem[1 + NMAX];
int dist[1 + NMAX];

vector < Edge > g[1 + NMAX];

void addedge(int i, int j){
  Edge direct = {j, g[j].size(), 0, cap[i][j]};
  Edge inverse = {i, g[i].size(), 0, cap[j][i]};

  g[i].push_back(direct);
  g[j].push_back(inverse);
}

bool bfs(){
  queue < int > q;
  fill(dist + 1, dist + n + 1, -1);
  dist[src] = 0;
  q.push(src);
  while(!q.empty()){
    int from = q.front();
    q.pop();
    for(int i = 0; i < g[from].size(); i++){
      Edge &e = g[from][i];
      if(dist[e.to] < 0 && e.flow < e.cap){
        dist[e.to] = dist[from] + 1;
        q.push(e.to);
      }
    }
  }
  return (0 <= dist[dest]);
}

int dfs(int from, int deltaflow){
  if(from == dest){
    return deltaflow;
  } else {
    for(int i = rem[from]; i < g[from].size(); i++){
      Edge &e = g[from][i];
      if(dist[e.to] == dist[from] + 1){
        int addflow = dfs(e.to, min(deltaflow, e.cap - e.flow));
        if(0 < addflow){
          e.flow += addflow;
          g[e.to][e.rev].flow -= addflow;
          rem[from] = i;
          return addflow;
        }
      }
    }
    return 0;
  }
}

int maxflow(){
  int result = 0;
  while(bfs()){
    fill(rem + 1, rem + n + 1, 0);
    while(int deltaflow = dfs(src, INT_MAX)){
      result += deltaflow;
    }
  }
  return result;
}

int main()
{
  in >> n;
  src = 1;
  dest = n;
  for(int i = 1; i <= n; i++){
    for(int j = 1; j <= n; j++){
      in >> cap[i][j];
    }
  }

  for(int i = 1; i <= n; i++){
    for(int j = i + 1; j <= n; j++){
      if(cap[i][j] != 0 || cap[j][i] != 0)
        addedge(i, j);
    }
  }

  out << maxflow() << '\n';

  in.close();
  out.close();
  return 0;
}